반응형

// // 기본적으로 현재날짜와 시간으로 설정된다.

//    Calendar today = Calendar.getInstance();    

//    System.out.println("이 해의 년도 : " + today.get(Calendar.YEAR));

//    System.out.println("월(0~11, 0:1월): " + today.get(Calendar.MONTH));

//    // (today.get(Calendar.MONTH) + 1)) 이런 형식으로 하면 다음월을 받아 올 수 

//    // 있다. today.get(Calendar.MONTH) + 1로 하면 이상한 값이 나온다. (괄호유무)

//    System.out.println("월(0~11, 0:1월): " + (today.get(Calendar.MONTH) + 1));

//    System.out.println("이 해의 몇 째 주: " + today.get(Calendar.WEEK_OF_YEAR));

//    System.out.println("이 달의 몇 째 주: " + today.get(Calendar.WEEK_OF_MONTH));

//    // DATE와 DAY_OF_MONTH는 같다.

//    System.out.println("이 달의 몇 일: " + today.get(Calendar.DATE));

//    System.out.println("이 달의 몇 일: " + today.get(Calendar.DAY_OF_MONTH));

//    System.out.println("이 해의 몇 일: " + today.get(Calendar.DAY_OF_YEAR));

//    // 1:일요일, 2:월요일, ... 7:토요일

//    System.out.println("요일(1~7, 1:일요일): " + today.get(Calendar.DAY_OF_WEEK)); 

//    System.out.println("이 달의 몇 째 요일: " + today.get(Calendar.DAY_OF_WEEK_IN_MONTH));

//    System.out.println("오전_오후(0:오전, 1:오후): " + today.get(Calendar.AM_PM));

//    System.out.println("시간(0~11): " + today.get(Calendar.HOUR));

//    System.out.println("시간(0~23): " + today.get(Calendar.HOUR_OF_DAY));

//    System.out.println("분(0~59): " + today.get(Calendar.MINUTE));

//    System.out.println("초(0~59): " + today.get(Calendar.SECOND));

//    System.out.println("1000분의 1초(0~999): " + today.get(Calendar.MILLISECOND));

//    // 천분의 1초를 시간으로 표시하기 위해 3600000으로 나누었다.(1시간 = 60 * 60초)

//    System.out.println("TimeZone(-12~+12): " + 

//    (today.get(Calendar.ZONE_OFFSET)/(60*60*1000))); 

//    // 이 달의 마지막 일을 찾는다.

//    System.out.println("이 달의 마지막 날: " + today.getActualMaximum(Calendar.DATE) );





(1) YYYYMMDD 문자 Calendar 로 넘겨주기


String select_Date = "20150101";

Calendar month = Calendar.getInstance();

SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");

month.setTime(formatter.parse( select_Date ));





(2) Calendar 날짜 String 으로 뽑아주기


String date = ""+new SimpleDateFormat("yyyyMMdd").format(calendarData.getTime());


or


String selectDate = "" + android.text.format.DateFormat.format("yyyyMMdd", calendarData);


출처 : https://m.blog.naver.com/PostView.nhn?blogId=komgurrbs&logNo=220262403979&proxyReferer=https:%2F%2Fwww.google.com%2F

반응형
,
반응형

이번 포스트에서는 스크롤뷰(ScrollView)의 자동 스크롤 방법에 대해 알아 보도록 하겠습니다.


맨 위 / 아래로 ScrollView 자동 스크롤

ScrollView 의 맨 위/아래로 자동 스크롤 하는 방법은 fullScroll을 사용하는 방법입니다.

인자값으로는 ScrollView.FOCUS_DOWN 과 ScrollView.FOCUS_UP 이 있습니다.

final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollview));
scrollview.post(new Runnable() {
    @Override
    public void run() {
        scrollview.fullScroll(ScrollView.FOCUS_DOWN);
    }
});



ScrollView 자동 스크롤 - 기본 함수 사용

특정 위치만큼만 스크롤 하려면 아래와 같이 smoothScrollBy() 혹은 smoothScrollTo() 함수를 이용하면 됩니다.

final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollview));
scrollview.post(new Runnable() {
    @Override
    public void run() {
        scrollview.smoothScrollBy(0, 800);
    }
});



ScrollView 자동 스크롤 - 스크롤 속도 변경

위에 소개된 함수들은 스크롤 속도가 정해져 있어 속도를 느리게 하고 싶으신 분들은 아래와 같은 방법으로 스크롤 속도를 조절할 수 있습니다.

* scrollTo 는 스크롤 하고 싶은 곳의 Y 값, 만약 맨 안래로 하고 싶으면 scrollView.getBottom() 을 넣어주면 됨.

final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollview));
scrollview.post(new Runnable() {
    @Override
    public void run() {
        ObjectAnimator.ofInt(scrollView, "scrollY",  scrollTo).setDuration(duration).start();
    }
});




출처: https://tiann.tistory.com/13 [티앤의 IT월드]

반응형
,
반응형

add 와 replace 중요성의 차이점은 replace 가 기존의 조각을 제거하고 새로운 조각을 추가하는 것입니다. 즉, 다시 버튼을 누르면 대체 된 프래그먼트가 호출되고 onCreateView가 호출됩니다. add 는 기존의 조각을 유지하고 기존의 조각이 활성화 될 것이라는 의미의 새 조각을 추가하는 반면 '뒤로'단추를 누르면 onCreateView가 기존 조각 (새 조각 전에 있던 단편 조각이 추가됨). 프래그먼트의 라이프 사이클 이벤트 onPause와 관련하여, onResume, onCreateView 및 기타 라이프 사이클 이벤트는 replace 될 경우 호출되지만 add 경우에는 호출되지 않습니다.



add()
 와 replace() 기본적인 차이점은 다음과 같이 설명 할 수 있습니다.

  • add() 는 일부 루트 요소에 단편을 단순히 추가하는 데 사용됩니다.
  • replace() 비슷하게 동작하지만 이전에는 이전 조각을 제거한 후 다음 조각을 추가합니다.

addToBackStack() 을 add() 또는 replace() 와 함께 사용하면 정확한 차이를 확인할 수 있습니다.

add() ... onCreateView가 호출되지 않았을 때 back button을 누르면, replace() 경우에는 back 버튼을 누르면 ... oncreateView가 매번 호출됩니다.


출처 : https://code.i-harness.com/ko/q/11c55df

반응형
,
반응형

Fragment 의 life cycle



fragment


  1. activity 를 만들기 시작
  2. fragment inflate 하고
  3. fragment 를 activity 에 attach 하고
  4. fragment 를 만들기 시작
  5. fragment 가 가지고 있는 view 를 만들기 시작
  6. view state 복원




----



  1. activity 가 create 하기 시작하면서(Activity.onCreate())
  2. activity 안의 fragment 를 inflate 한다.(Fragment.onInflate())
  3. 이 inflate 한 녀석이 activity 에 붙여지고 나서,(Fragment.onAttach())
  4. 부모가 없는 Fragment(최상위 fragment ?) 가 Activity 에 attach 됐다고 알린다.(Activity.onAttachFragment())
  5. fragment 가 create 가 시작되고,(Fragment.onCreate())
  6. fragment 안의 view 를 만들기 시작한다.(Fragment.onCreateView())
  7. 이 과정이 끝나면 activity 의 create 가 끝난것이다.(Fragment.onActivityCreate())
  8. 그리고 나면, 이제 View 가 가지고 있던 State 를 복원하기 시작한다.(Fragment.onViewStateRestored())





  1. Activity.onCreate()
    • handleLaunchActivity() > performLaunchActivity() > callActivityOnCreate() > performCreate() > onCreate()
  2. Fragment.onInflate()
    • Activity.onCreate() > setContentView > inflate() > onCreateView()  > onInflate()
  3. Fragment.onAttach()
    • Activity.onCreate() > setContentView > inflate() > onCreateView() > addFragment() > moveToState() > Fragment.INITIALIZING > onAttach()
  4. Activity onAttachFragment()
    • Activity.onCreate() > setContentView > inflate() > onCreateView() > onCreateView() > addFragment() > moveToState() > Fragment.INITIALIZING > onAttachFragment()
  5. Fragment.onCreate()
    • onCreate() > setContentView > inflate() > onCreateView() > addFragment() > moveToState() > Fragment.INITIALIZING > performCreate() > onCreate()
  6. Fragment.onCreateView()
    • onCreate() > setContentView > inflate() > onCreateView()  > addFragment() > moveToState() > Fragment.INITIALIZING > performCreateView() > onCreateView()
  7. Fragment.onActivityCreated()
    • handleLaunchActivity() > performLaunchActivity() > callActivityOnCreate() > performCreate() > dispatchActivityCreated() > moveToState() > Fragment.CREATED > performActivityCreated() > onActivityCreated()
  8. Fragment.onViewStateRestored()
    • handleLaunchActivity() > performLaunchActivity() > callActivityOnCreate() > performCreate() > dispatchActivityCreated() > moveToState() > Fragment.CREATED > restoreViewState > onViewStateRestored()






    Activity Life cycle


    from : Androidify workshop



    See Also

    1. http://stackoverflow.com/questions/14021600/fragment-viewstate-restored-in-onstart


    반응형
    ,
    반응형
    public abstract class AbsFragmentNew<T extends Object> extends Fragment

    이런 class를 만들 때 "T"의 데이터 타입을 알아내기 위한 방법

    Type superclass = getClass().getGenericSuperclass();
    if(superclass instanceof ParameterizedType) {
    Type[] genericTypes = ((ParameterizedType) superclass).getActualTypeArguments();
    if (genericTypes.length > 0) {
    try {
    Type genericType = genericTypes[0];
    String className = genericType.toString().split(" ")[1];
    classType = (Class<T>) Class.forName(className);
    } catch (ClassNotFoundException e) {
    Log.e(TAG, e);
    }
    }
    }


    반응형
    ,
    반응형

    GC는 Garbage Collector의 약자입니다


    dalvikvm Tag 로 


    GC_CONCURRENT freed 11405k, 59% free 3107K/7431K, external 3299k/4120k, puased 4ms+3ms


    라는 log가 찍힙니다. 


    다음과 같은 format으로 로그가 찍힙니다.


    [Reason] [Amount Freed], [Heap Statistics], [External Memory Statistics], [Pause Time]


    [Reason] : GC 발동의 원인을 나타냅니다.


    1. GC_FOR_MALLOC : 객체 생성의 있어서 힘에 메모리를 할달 받아야 할 때 힙에 남아있는 사용가능한 메모리 공간이 충분치 않을때.

    2. GC_EXPLICIT : GC가 명시적으로 불렸을 때. Runtime.gc(), VMRuntime.gc(), SIGUSR1 등.

    3. GC_CONCURRENT : 힙의 사용 한계점(사용 한계점은 내부적으로 정해진다.)을 넘어섰을때.

    4. GC_EXTERNAL_ALLOC : VM이 garbage 될 객체들이 사용하고 있는 공간을 그렇지 않은 객체들을 위해 공간을 미리 확보하려 할때.

    5. GC_HPROF_DUMP_HEAP : 힙의 컨텐츠를 파일로 저장할 때(WITH_HPROF flag를 사용할 때만)


    [Amount Freed] : 말 그대로 읽은 파일의 Kbyte를 나타낸다.


    [Heap Statistics] : GC가 발동 된 이후의 상태를 말한다. 


    59% free 3107K/7431K => 남은 공간 59%, 사용중인 공간 3107K, 힙의 총 사이즈 7413K


    [External Memory Statistics] : 외부 메모리 관련인데.... Bitmap 관련해서 외부메모리 따로 할당하는 것인데... 잘 이해가 안가서 생략.... ㅈㅅ (Bitmap 관련해서 따로 메모리를 쓰는 경우가 아니라면 값이 변하지 않는 것 같습니다.)


    [Pause Time] : GC로 인해 일시정지된 시간 (milliseconds)


    4ms+3ms => GC_CONCURRENT 일때에만 2개의 []ms+[]ms 꼴로 출력된다. 앞의 []ms는 GC가 발동되기 이전의 pause 시간이고, 뒤의 []ms는 garbage collecting이 거의 완료된 순간에 pause된 시간이다. 


    참고 문헌 : http://stackoverflow.com/questions/4976566/what-do-gc-for-malloc-gc-explicit-and-other-gc-mean-in-android-logcat 


    반응형
    ,
    반응형

    Imgur Shared Element Transition

    Activity Shared Elements Transitions

    Note that the shared element transitions require Android 5.0 (API level 21) and above and will be ignored for any lower API versions. Be sure to check the version at runtime before using API 21 specific features.

    1. Enable Window Content Transitions

    Enable Window Content Transitions in your styles.xml file:

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="android:windowContentTransitions">true</item>
        ...
    </style>

    2. Assign a Common Transition Name

    Assign a common transition name to the shared elements in both layouts. Use theandroid:transitionName attribute.

    For e.g. in MainActivity.xml:

    <android.support.v7.widget.CardView
      ...>
          <ImageView
              android:id="@+id/ivProfile"
              android:transitionName="profile"
              android:scaleType="centerCrop"
              android:layout_width="match_parent"
              android:layout_height="160dp" />
          ...
    </android.support.v7.widget.CardView>

    In DetailActivity.xml:

    <LinearLayout
      ...>
          <ImageView
              android:id="@+id/ivProfile"
              android:transitionName="profile"
              android:scaleType="centerCrop"
              android:layout_width="match_parent"
              android:layout_height="380dp" />
          ...
    </LinearLayout>

    Note that it doesn't matter if the android:id is different or where in the layout hierarchy the source and target views exist.

    3. Start Activity

    Start the target activity by specifying a bundle of those shared elements and views from the source.

    Intent intent = new Intent(this, DetailsActivity.class);
    // Pass data object in the bundle and populate details activity.
    intent.putExtra(DetailsActivity.EXTRA_CONTACT, contact);
    ActivityOptionsCompat options = ActivityOptionsCompat.
        makeSceneTransitionAnimation(this, (View)ivProfile, "profile");
    startActivity(intent, options.toBundle());

    Thats it! Specifying the source view along with the transition name ensures that even if you have multiple views with the same transition name in the source hierarchy, it will essentially be able to pick the right view to start the animation from.

    To reverse the scene transition animation when you finish the second activity, call theActivity.supportFinishAfterTransition() method instead of Activity.finish(). Also, you will need to override the behavior of the home button in the ToolBar/ ActionBar for such cases:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            // Respond to the action bar's Up/Home button
            case android.R.id.home:
                supportFinishAfterTransition();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    4. Multiple Shared Elements

    Sometimes, you might want to animate multiple elements from the source view hierarchy. This can be achieved by using distinct transition names in the source and target layout xml files.

    Intent intent = new Intent(context, DetailsActivity.class);
    intent.putExtra(DetailsActivity.EXTRA_CONTACT, contact);
    Pair<View, String> p1 = Pair.create((View)ivProfile, "profile");
    Pair<View, String> p2 = Pair.create(vPalette, "palette");
    Pair<View, String> p3 = Pair.create((View)tvName, "text");
    ActivityOptionsCompat options = ActivityOptionsCompat.
        makeSceneTransitionAnimation(this, p1, p2, p3);
    startActivity(intent, options.toBundle());

    Note: By default android.util.Pair will be imported but we want to select theandroid.support.v4.util.Pair class instead.

    Be careful to not overdo transitions between shared elements. While it can make sense to have one cohesive unit animate from one screen to another (which may or may not contain multiple shared elements), having too many shared elements will result in a distracting animation which makes the experience more jarring.

    5. Customizing Shared Elements Transition

    In Android L, shared elements transition defaults to a combination of ChangeBounds,ChangeTransformChangeImageTransform, and ChangeClipBounds. This works well for most typical cases. However, you may customize this behavior or even define your own custom transition.

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- enable window content transitions -->
        <item name="android:windowContentTransitions">true</item>
    
        <!-- specify enter and exit transitions -->
        <!-- options are: explode, slide, fade -->
        <item name="android:windowEnterTransition">@transition/change_image_transform</item>
        <item name="android:windowExitTransition">@transition/change_image_transform</item>
    
        <!-- specify shared element transitions -->
        <item name="android:windowSharedElementEnterTransition">
          @transition/change_image_transform</item>
        <item name="android:windowSharedElementExitTransition">
          @transition/change_image_transform</item>
    </style>

    The change_image_transform transition in this example is defined as follows:

    <!-- res/transition/change_image_transform.xml -->
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
      <changeImageTransform/>
    </transitionSet>

    To enable window content transitions at runtime instead, call the Window.requestFeature()method:

    // inside your activity (if you did not enable transitions in your theme)
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    // set an enter transition
    getWindow().setEnterTransition(new Explode());
    // set an exit transition
    getWindow().setExitTransition(new Explode());

    See this official guide on Defining Custom Animations for more details.

    Fragment Shared Elements Transitions

    Leveraging shared element transitions works with fragments too in a similar way as was shown above for activities.

    Note that the shared element transitions require Android 5.0 (API level 21) and above and will be ignored for any lower API versions. Be sure to check the version at runtime before using API 21 specific features.

    Assign a Common Transition Name

    Within two fragments let's assign a common transition name to the shared elements in both layouts. Use the android:transitionName attribute and put the view inside bothFirstFragment and SecondFragment:

    <android.support.v7.widget.CardView
      ...>
          <ImageView
              android:id="@+id/ivProfile"
              android:transitionName="profile"
              android:scaleType="centerCrop"
              android:layout_width="match_parent"
              android:layout_height="160dp" />
          ...
    </android.support.v7.widget.CardView>

    Define the Transition

    Add a transition to the res/transition folder named change_image_transform.xml with the following:

    <?xml version="1.0" encoding="utf-8"?>
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
        <changeImageTransform />
    </transitionSet>

    Animate Transition in FragmentTransaction

    Now within the activity, we can trigger the transition as part of any FragmentTransaction:

    // Get access to or create instances to each fragment
    FirstFragment fragmentOne = ...;
    SecondFragment fragmentTwo = ...;
    // Check that the device is running lollipop
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Inflate transitions to apply
        Transition changeTransform = TransitionInflater.from(this).
              inflateTransition(R.transition.change_image_transform);
        Transition explodeTransform = TransitionInflater.from(this).
              inflateTransition(android.R.transition.explode);
    
        // Setup exit transition on first fragment
        fragmentOne.setSharedElementReturnTransition(changeTransform);
        fragmentOne.setExitTransition(explodeTransform);
    
        // Setup enter transition on second fragment
        fragmentTwo.setSharedElementEnterTransition(changeTransform);
        fragmentTwo.setEnterTransition(explodeTransform);
    
        // Find the shared element (in Fragment A)
        ImageView ivProfile = (ImageView) findViewById(R.id.ivProfile);
    
        // Add second fragment by replacing first 
        FragmentTransaction ft = getFragmentManager().beginTransaction()
                .replace(R.id.container, fragmentTwo)
                .addToBackStack("transaction")
                .addSharedElement(ivProfile, "profile");
        // Apply the transaction
        ft.commit();
    }
    else {
        // Code to run on older devices
    }

    Note that we need use methods on the exiting fragment such assetSharedElementReturnTransition and setExitTransition. On the entering fragment, we call setSharedElementEnterTransition and setEnterTransition. Finally we need to find the instance of the shared element and then call addSharedElement(view, transitionName) as part of building the FragmentTransaction. Additional external resources for fragment-to-fragment shared element transitions include:

    With that you can apply these handy transitions to fragments as well as to activities.


    출처: https://github.com/codepath/android_guides/wiki/Shared-Element-Activity-Transition

    반응형
    ,
    반응형
    Log.i(TAG, "BOARD = " + Build.BOARD);
    Log.i(TAG, "BRAND = " + Build.BRAND);
    Log.i(TAG, "CPU_ABI = " + Build.CPU_ABI);
    Log.i(TAG, "DEVICE = " + Build.DEVICE);
    Log.i(TAG, "DISPLAY = " + Build.DISPLAY);
    Log.i(TAG, "FINGERPRINT = " + Build.FINGERPRINT);
    Log.i(TAG,  "HOST = " + Build.HOST);
    Log.i(TAG, "ID = " + Build.ID);
    Log.i(TAG, "MANUFACTURER = " + Build.MANUFACTURER);
    Log.i(TAG, "MODEL = " + Build.MODEL);
    Log.i(TAG, "PRODUCT = " + Build.PRODUCT);
    Log.i(TAG, "TAGS = " + Build.TAGS);
    Log.i(TAG, "TYPE = " + Build.TYPE);
    Log.i(TAG, "USER = " + Build.USER);
    Log.i(TAG, "VERSION.RELEASE = " + Build.VERSION.RELEASE);


    반응형
    ,
    반응형
    반응형
    ,
    반응형

    기존 Android SDK 버전에서는 설치 시 해당 앱에 설정 된 permission을 물어보고 동의를 해야만 설치가 가능했다. 하지만, Android 6.0(SDK 23)이상의 버전에서는 설치 시에 묻는게 아니라 해당 기능이 permission을 필요로 할 때, permission을 활성화 해줘야 사용가능하다. 따라서 기존 6.0미만의 버전에서 개발했던 어플리케이션은 6.0이상의 폰에서는 정상적으로 작동하지 않을 수 있다.


    따라서, 각 기능이 필요한 시점마다 권한을 받아야 한다.

    이곳에 들어가면

     https://github.com/henryJung/android_runtime_permission 

    자세히 확인 할 수 있다.


    런타인 퍼미션을 적용해야 할 퍼미션 목록이다. 

    Permission GroupPermissions
    CALENDAR
    CAMERA
    CONTACTS
    LOCATION
    MICROPHONE
    PHONE
    SENSORS
    SMS
    STORAGE


    반응형
    ,