original source : https://youtu.be/rWQ9LR4Hk80

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

original source: https://youtu.be/vFfbb1bfvhA

image

openFileInput()은 context의 method이다. 내장 메모리내의 package의 공간에 접근하는 경우외에는 android에서 제공되는 File class나 file path를 FileInputStrem()에 construct arg로 전달해서 FileInputStrem obj를 만든다.

openFileInput -> InputStreamReader -> BufferedReader -> StringBuilder를 이용해서 읽어낸다.

===========================================================

image

MODE_PRIVATE이 내장메모리에 쓸때 기본으로적용되는 mode이다. 

MODE_APPEND, MODE_WORLD_WRITEABLE등이 있다.

참조) android docs   https://developer.android.com/reference/android/content/Context#MODE_PRIVATE

openFileOutput -> BufferedWriter 를 이용해 파일을 쓴다.

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

모니터하는 path는 미리 존재하고 있어야 하므로 보통 실제 존재하는지 확인하고 observing 작업을 한다. recursive하게 observing하지는 않는다.

===========================================================

===========================================================

===========================================================

===========================================================

original source : https://youtu.be/h71-G8T73Hk

===========================================================

===========================================================

===========================================================

===========================================================

===========================================================

context obj를 이용하여 내외장에 있는 내 자신 app package 폴더에 접근할수 있다.

===========================================================

내자신 app관련 파일이 내외장 폴더에 존재하는 예시를 보여주고 있다.

===========================================================

Environment obj를 통해 접근 가능하다.

===========================================================

===========================================================

original source : https://youtu.be/bJb6qJ5FrtU

image

===========================================================

image

networkinfo는 conncetiviymanager에서 getActiveNetworkInfo를 통해 얻는다.

===========================================================

image

===========================================================

image

===========================================================

image

requestRouteToHost를 통해 실제 host까지의 network가 연결되어 있는지를 확인할수 있다.

===========================================================

image

network 변화를 감지하는 receiver를 만들수 있다. 이때 발생하는 이벤트의 이름은 CONNECTIVITY_ACTION이다. 이 이벤트는 manifest의 intent-filter로 설정하면 감지할수 없고 registerReceiver()를 통해 코드로 등록되어야 한다. 

===========================================================

image

CONNECTIVITY_ACTION 이벤트를 감지한 receiver에서 전달되어 들어오는 intent에서 얻을수 있는 추가 정보를 설명하고 있다.

===========================================================

image

original source : https://ranyalbegwein.silvrback.com/transforming-image-behavior

참고자료 ) https://www.androidauthority.com/using-coordinatorlayout-android-apps-703720/

coordinatorlayout을 이용해서 구현가능한 작업 예시

1. Intro

A CoordinatorLayout is this thing:

public class CoordinatorLayout extends ViewGroup implements NestedScrollingParent {
    ... 
}

from the support library ( compile 'com.android.support:design:25.3.1' ), which seems at first like an innocent old FrameLayout, until you discover its real powers – Behaviors!

CoordinatorLayout는 기본적으로 FrameLayout이다. 

A Behavior is an object attached to a child of a CoordinatorLayout, which defines its interaction with another View, ( a dependency) within the same layout.

CoordinatorLayout 아래에 있는 한 element가 다른 View(dependency라고 불리는) 의 변화에 따라 어떻게 변화할것인지를  정의하고 있는 object가 Behavior 이다. 상태변화가 관찰되어지는 View를 dependency라고 한다. 

So, a CoordinatorLayout monitors every movement of its children, and notifies the ones with attached Behaviors for a dependency change.

Something like this:

The SnackBar here is called a dependency – which makes sense, because the child depends on its movement in order to behave in a certain way specified by its attached Behavior.

Following Material Design guidelines, this behavior is the correct interaction between a SnackBar and a FloatingActionButton.

2. Let’s get started!

Everything should run in a context or under the supervision of a CoordinatorLayout, so let’s create a fresh Activity with a CoordinatorLayout as its content-view root element.

Create a new project, and add a new Activity by selecting the “Basic Activity” template:

Take a look at activity_main.xml, it should contain the following:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.rany.albeg.wein.behaviors.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

Since the default behavior of FloatingActionButton is to run away from the SnackBar like we wish to implement ourselves, take it off of the XML tree and insert something like an AppCompatButton:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout>

     ...

    <android.support.v7.widget.AppCompatButton
        android:id="@+id/bt_click_me"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:text="Click me"/>

</android.support.design.widget.CoordinatorLayout>

Edit MainActivity accordingly, and modify onCreate():

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        AppCompatButton btn = (AppCompatButton) findViewById(R.id.bt_click_me);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Yeah buddy!", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

3. Implementation

To create a Behavior we’ll need to create a class that extends CoordinatorLayout.Behavior<V>where V is a type of a class which extends View and represents the type of the child – in our case it’ll be AppCompatButton:

public class CustomMoveUpBehavior extends 
                                  CoordinatorLayout.Behavior<AppCompatButton> {
    ...
}

We’re almost done! To complete programming our custom behavior and define the unique interaction between a child and a dependency, we’ll need to:

  • Override layoutDependsOn(...)

This method gets called ( at least once in response to a layout request ) by the parent CoordinatorLayout to determine whether the supplied child view has another specific sibling view as a layout dependency.
In other words, CoordinatorLayout sees the SnackBar and asks us :

“Hey, is this AppCompatButton depends on this SnackBar ?” and we should answer “Yes!” in order to further react in accordance to SnackBar’s movement:

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent,
                                   AppCompatButton child,
                                   View dependency) {

        return dependency instanceof Snackbar.SnackbarLayout;
    }

위의 코드를 설명하면 CoordinatorLayout내의 element 상태가 변화하면 CoordinatorLayout는 layoutDependsOn()를 통하여 View obj인 dependency가 Snackbar.SnackbarLayout instance인지 확인한다. 맞으면 true를 return한다. CoordinatorLayout는 자신의 모든 child element를 이 함수layoutDependsOn()에 넣어 해당 View가 dependency가 맞는지 아닌지 확인한다. 사실 layoutDependsOn()는 상태 변화에도 호출되지만 최초로 화면이 구성될때도 호출된다.

  • Override onDependentViewChanged(...)

This method gets called by the parent CoordinatorLayout after the relevant layoutDependsOn(...)returns true, in which we need to actually move stuff!

In our case, for the button to run away from the SnackBar, we’ll want to translate its Y position to be the difference between SnackBar’s current Y translation and its height!

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent,
                                          AppCompatButton child,
                                          View dependency) {

        float tY = dependency.getTranslationY() - dependency.getHeight();
        child.setTranslationY(tY);
        return true;
    }

위위의 코드 layoutDependsOn 의 과정을 거쳐 dependency의 변화가 관측되었다면 onDependentViewChanged()에 전달된 상태변화가 감지된 dependency와 그에 따라 조정이 필요한 child view를 함수내에서 조정한다.  

We return true to say: “Hey CoordinatorLayout! Our Behavior changed AppCompatButton’s position”

CustomMoveUpBehavior is done and ready to be attached!

There are several ways to attach a Behavior to View, and I’ll choose to go with the common way – via XML.

In order to attach CustomMoveUpBehavior to AppCompatButton via XML, add the following constructor first:

public CustomMoveUpBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
}

and now jump into activity_main.xml and just add the following attribute to AppCompatButton’s XML tag:

    <android.support.v7.widget.AppCompatButton
    ...
        app:layout_behavior="your.package.name.CustomMoveUpBehavior"
    ...
    />

replacing your.package.name as necessary.

https://youtu.be/iZ4spzwjt8E

15:36 layout transition animation 은 layout내에 있는 view가 생성되거나 삭제될때 사용되는 transition animation을 말한다. 

 23:17 activity transition animation은 한 activity에서 다른 activity로 전환될대 사용되는 transition animation을 말한다. 

25:12 fragment 전환 animation은 fragment 생성, 제거, 교환, backstack에서 pop 시에 사용되는 animation을 말한다. 

 TextSwitcher 예시 https://youtu.be/Aybw0wDeaSQ 

ImageSwitcher 예시 https://youtu.be/WS1Ta_S3WYI?t=788 

ViewFlipper 예시 https://youtu.be/2c-GbJ-c_eA 

AdapterViewFlipper 예시 https://youtu.be/2jiiUqlKCaQ

original source : https://github.com/harism/android-pagecurl

original source : https://github.com/openaphid/android-flip

android에서 activity 전환시 flip animation (책장 넘기는 듯한 애니메이션)을 구현하는 library