Android Support Library

Android Support Library

log화일 작성을 위해서는 import android.util.Log를 한후 사용한다. 개발시 효율적인 log 관리를 위해 private static final TAG = “테그이름” 을 만들고 Log 작성시 이 tag를 이용한다.  https://youtu.be/9LbETUPM_sY?t=35

auto generate을 위한 단축키는 alt + ins 이를 통해 override function이나 setter getter함수를 쉽게 만들수 있다. https://youtu.be/9LbETUPM_sY?t=45

모든 activity는 manifest 에 명기되어야 한다.

log 출력창 열기

image

tag를 이용한 log filter

image

values/strings.xml 을 통해 사용되는 문자열을 hard coded가 아닌 가변적으로 사용가능하다.  문자열을 사용할때는@string/변수이름

https://youtu.be/72mf0rmjNAA?t=275

@+id/이름

@+id/이름 , @string/변수이름  등과 같은 레퍼런스에 ctrl를 누를 상태로 마우스를 가져다 대면 본래 정의 되어있는 코드로 이동가능하능한 링크가 만들어 진다. 

activity의 onCreate() 내에서 setContentView(R.layout.레이아웃이름) 을 통해 layout을 load 한다.

android studio ui 창을 이용하지 않고 code로 element를 loadj하는 경우 import android.widget.RelativeLayout, import android.widget.Button 과 같이 먼저 import해야 한다. 그리고 obj를 생성하고 레이아웃obj.addView()를 이용해서 element를 덧붙일수 있다. 그리고 setContentView(레이아웃obj) 를 통해 비쥬얼라이즈 한다.

code에서 생성된 element의 높이 너비 위치를 결정하는 경우

레이아웃obj.LayoutParams obj와 이 obj의 AddRule()를 이용한다.

https://youtu.be/RLDqbEhUjVk?t=370

element obj의 setId() 를 통해 id를 설정한다.

엘레먼트 obj의 setMargin()을 통해 margin 설정

엘레먼트obj.setWidth() 를 통해 폭을 지정할수 있다.

wrap_content, fill_parent

layout:lowSpan , layout:columnSpan 을 통해 gridlayout에서 cell 크기를 확장할수 있다.

layout:gravity를 통해 확장된 cell안에서의 element위치를 결정할수 있다. 

https://youtu.be/4bXOr5Rk1dk?t=483

onCreate()안에서 element를 찾아서 event listener를 연결한다.  

Button 버튼변수이름 = (Button)findViewByID(R.id.아이디)  와 같은 형식으로 element를 찾아낸다

버튼변수이름. setOnClickListener(

     new Button.onClickListener(){

          public void onClick(View v){

               …

          }

     }

)  와 같은 형태로 listener가 등록된다.

https://youtu.be/jxoG_Y6dvU8?t=110

텍스트뷰obj.setText() 를 통해 text를 변경가능

버튼변수이름.setOnLongClickListener(

    new Button.onClickListener(){

         public void onClick(View v){

              …

              return true; // 이를 통해 long click event가 처리되면 다른 listener가 작동 X

         }

    }

)

java는 명령문 끝에 ; 를 붙인다(swift는 없음). java는 type 종류를 변수 앞에 붙여준다. (swift는  변수 이름 뒤에 : 를 붙이고 그 뒤에 type종류를 명기한다.)

gesture와 doulbe tap gesture를 사용하는 경우

import android.view.MotionEvent

import android.view.GestureDetector

import android.support.v4.view.GestureDectorCompat

하고 activity는 implements GestureDetector.onGestureListener, GestureDetector.onDoubleTapListener. alt+ins 를 통해  ilstener의 method를 override하고 각각의 method내에서의 작업 마지막에는 return true를 명시해 이벤트가 잘 처리되었음을 알린다.

여러개의 activity에서 사용되는 공통된 부분은 fragment를 만들어 공유사용하는 방법이 있다.

adding image in project

image

fragment를 사용하는 경우 fragment xml 화일이 있어야 한다. 즉 하나의 fragment는 하나의 xml화일로 존재한다는 의미이며 이렇게 되어야 여러 activity에서 사용될수 있다.

xml element example

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/simpleTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="Before Clicking"
        android:textColor="#f00"
        android:textSize="25sp"
        android:textStyle="bold|italic"
        android:layout_marginTop="50dp"/>

fragment사용을 위한 import 작업

ref) https://developer.android.com/training/basics/fragments/creating

https://youtu.be/yOBQHf5nM2I?t=96

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;

fragment기본 양식

https://developer.android.com/guide/components/fragments#java

https://youtu.be/yOBQHf5nM2I?t=156

public static class ExampleFragment extends Fragment {
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
                            Bundle savedInstanceState) {
       // Inflate the layout for this fragment
       return inflater.inflate(R.layout.example_fragment, container, false);
   }
}

activity xml에 fragment xml 추가 하는 방법

image

fragment간 직접 data를 주고 받을수는 없고 activity를 거쳐서 data를 주고 받을수 있다.

fragment의 onAttach() – 이함수는 fragement가 activity에 연결될때 호출된다. onAttach() 함수 안에서 변수로 받은 중앙 activity의 obj를 fragment 내의 한 property에 할당하고 activity obj에 있는 interface method에 data를 전달한다. 그리고 activity에 정의된 interface method내에서 data를 처리하고 그것을 activity가 다른 fragment에 전달한다.  

https://youtu.be/MHHXxWbSaho?t=205

이때 activity에서 다른 fragment의 참조를 얻어내는 방법의 예

Frag2 fragmentObj=(Frag2) getSupportFragmentManager().findFragmentById(R.id.pager);

https://youtu.be/sPvCEsGm8us?t=30  

onCreateView()에서 fragment xml가 inflate되면 그 안의 element를 찾아 변수에 할당하는 작업이 일반적이다

https://youtu.be/vyykjIPNBXY?t=206

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.hello_world, container, false);
        View tv = v.findViewById(R.id.text);
        ((TextView)tv).setText("Fragment #" + mNum);
        tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
        return v;
    }

webview를 사용하는 경우

import android.webkit.WebView;
import android.webkit.WebViewClient;

를 통해 먼저 import 한다.  AndroidManifest.xml 에는 권한을 얻기 위해   <uses-permission android:name=“android.permission.INTERNET” /> 를 추가해준다.

master / detail flow 

https://youtu.be/iNzrUu784dY

image
image

overflow menu

https://youtu.be/iwE1bnRlZw0

image

overflow menu의 item은 res 폴더안의 menu폴더안에 정의되어있다. 각각의 메뉴 item은 group안에 그룹지워질수 있다. 

menu선택에 따른 작업 수행 

https://developer.android.com/guide/topics/ui/menus

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   // Handle item selection
   switch (item.getItemId()) {
       case R.id.new_game:
           newGame();
           return true;
       case R.id.help:
           showHelp();
           return true;
       default:
           return super.onOptionsItemSelected(item);
   }
}

menu생성시 호출

@Override
public boolean onCreateOptionsMenu(Menu menu) {
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.game_menu, menu);
   return true;
}

간단한 animation

https://youtu.be/n4IyvL-ACbk?t=780

https://robinhood.engineering/beautiful-animations-using-android-constraintlayout-eee5b72ecae3

TransitionManager.beginDelayedTransition(constraintLayout)

button에 setOnClickListener를 통해 listener를 연결해서 click event를 처리 할수 있지만 button의 onClick attributes를 지정해서 처리 할수도 있다.

https://youtu.be/06bcsMx-7QQ?t=245

https://youtu.be/mPGCLKRCG-8?t=60

activity 간 이동

아래와 같이 해서 다른 activity로 이동 가능하다.

import android.content.Intent

Intent 변수 = new Intent(this, 액티버티이름.class)

액티버티obj.putExtra(”키이름”, 값)

startActivity(변수)

https://youtu.be/mPGCLKRCG-8?t=180

다음 activity에 값을 전달하기 https://youtu.be/mPGCLKRCG-8?t=381

다음 activity에서 값을 받는 방법

Bundle 변수이름  = getIntent().getExtra() 

sending broadcast

https://developer.android.com/guide/components/broadcasts

https://youtu.be/X69q01TY1ic

Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data","Notice me senpai!");
sendBroadcast(intent);

broadcast receiver 만드는 방법

https://youtu.be/htU_Rd-DW2U

image

위와 같은 방법으로 기본틀의 java화일을 만들어 준다. 그리고 나서 manifest 화일에 

<receiver android:name=".MyBroadcastReceiver"  android:exported="true">
   <intent-filter>
       <action android:name="android.intent.action.BOOT_COMPLETED"/>
       <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
   </intent-filter>
</receiver>

와 비슷하게 등록해 주어야한다. 

https://developer.android.com/guide/components/broadcasts

toast 만드는 방법

import android.widget.Toast

Context context = getApplicationContext();
CharSequence text = "Hello toast!";
int duration = Toast.LENGTH_SHORT;

Toast toast = Toast.makeText(context, text, duration);
toast.show();

thread

handler, runnable, thread를 이용한 thread 작업 ( AsyncTask를 이용할수 있다. AsyncTask를 이용한 방법이 좀더 진화된 방법이라고 할수 있다. )

https://youtu.be/SCwU-gy3HoM

IntentService 를 사용하는 방법 

https://developer.android.com/guide/components/services

https://youtu.be/-sBxmjrSn34

<manifest ... >
 ...
 <application ... >
     <service android:name=".ExampleService" />
     ...
 </application>
</manifest>

서비스를 manifest화일에 위와 같이 등록한다.

서비스작업을 수행하는 java화일을 아래와 같이 만든다.

public class HelloIntentService extends IntentService {

 /**
  * A constructor is required, and must call the super <code><a href="/reference/android/app/IntentService.html#IntentService(java.lang.String)">IntentService(String)</a></code>
  * constructor with a name for the worker thread.
  */
 public HelloIntentService() {
     super("HelloIntentService");
 }

 /**
  * The IntentService calls this method from the default worker thread with
  * the intent that started the service. When this method returns, IntentService
  * stops the service, as appropriate.
  */
 @Override
 protected void onHandleIntent(Intent intent) {
     // Normally we would do some work here, like download a file.
     // For our sample, we just sleep for 5 seconds.
     try {
         Thread.sleep(5000);
     } catch (InterruptedException e) {
         // Restore interrupt status.
         Thread.currentThread().interrupt();
     }
 }
}

intentService가 아닌 그냥 Service

https://youtu.be/9YapLOfQ-dY

synchronized와 wait에 관련된 내용 – https://www.youtube.com/watch?v=RH7G-N2pa8M

synchronized(this) 관련 내용 – https://stackoverflow.com/questions/13264726/java-syntax-synchronized-this

listview, gridview 

The ListView and GridView are subclasses of AdapterView and they can be populated by binding them to an Adapter, which retrieves data from an external source and creates a View that represents each data entry.

Android provides several subclasses of Adapter that are useful for retrieving different kinds of data and building views for an AdapterView ( i.e. ListView or GridView). The common adapters are ArrayAdapter,Base Adapter,CursorAdapter, SimpleCursorAdapter,SpinnerAdapter and WrapperListAdapter.

listview를 activity layout에 넣기

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   tools:context=".ListActivity" >

   <ListView
      android:id="@+id/mobile_list"
      android:layout_width="match_parent"
      android:layout_height="wrap_content" >
   </ListView>
 
</LinearLayout>

activity_listview.xml list item 하나의 디자인

<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/label"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:padding="10dip"
   android:textSize="16dip"
   android:textStyle="bold" >
</TextView>
// Array of strings...
   String[] mobileArray = {"Android","IPhone","WindowsMobile","Blackberry",
      "WebOS","Ubuntu","Windows7","Max OS X"};
   
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      
      ArrayAdapter adapter = new ArrayAdapter<String>(this, 
         R.layout.activity_listview, mobileArray);
      
      ListView listView = (ListView) findViewById(R.id.mobile_list);
      listView.setAdapter(adapter);
   }

데이터 소스를 array형태로 만들고 이를 가지고 ArrayAdapter를 만들고 이를 listView에 연결한다.

https://www.tutorialspoint.com/android/android_list_view.htm

https://youtu.be/A-_hKWMA7mk

list item click 처리하는 방법

https://youtu.be/A-_hKWMA7mk?t=280

https://stackoverflow.com/questions/2468100/how-to-handle-listview-click-in-android

listViewObj.setClickable(true);
listViewObj.setOnItemClickListener(new AdapterView.OnItemClickListener() {

  @Override
  public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {

    Object o = listViewObj.getItemAtPosition(position);
    /* write you handling code like...
    String st = "sdcard/";
    File f = new File(st+o.toString());
    // do whatever u want to do with 'f' File object
    */  
  }
});

또는

listViewObj.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // When clicked, show a toast with the TextView text or do whatever you need.
        Toast.makeText(getApplicationContext(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
    }
});

프로젝트에 image를 넣는 경우

drawable폴더에 넣는다.

image

custom list item을 사용하는 경우

custom item design과 custom adapter가 필요하다.

https://youtu.be/nOdSARCVYic

https://www.journaldev.com/10416/android-listview-with-custom-adapter-example-tutorial

java는 기본적으로 클래스 이름과 같은 이름의 함수가 constructor가 된다. 

sqlite를 데이터베이스로 사용하는 방법

https://youtu.be/Jcmp09LkU-I

https://www.androidhive.info/2011/11/android-sqlite-database-tutorial/

model 역활을 하는 java 화일이 필요하다 그 화일안에는 we define the SQLite table name, column names and create table SQL query along with getter / setter methods. ( 기본으로 constructor, onCreate, onUpgrade함수를 가지고 있어야 한다. )

또한 perform the CRUD operations 하기 위해서 SQLiteOpenHelper.를 extends하는 java 화일이 필요하다. 

video를 플레이하는 방법

videoView와 mediaController를 이용한다.

https://youtu.be/oF9yZenJtjI

http://www.zoftino.com/android-videoview-mediacontroller-playing-videos-tutorial

take a photo and use the picture

https://youtu.be/my8PSy2DBsY

needed for taking photo – modify manifest화일 android.hardware.Camera

https://youtu.be/my8PSy2DBsY?t=240

checking if there is camera or not

https://youtu.be/k1Wc0vmD284

https://guides.codepath.com/android/Accessing-the-Camera-and-Stored-Media

import android.content.pm.PackageManager;

PackageManager pm = context.getPackageManager();

if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
}

take photo and get result

public final static int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1034;
// create Intent to take a picture and return control to the calling application
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
...
...
// Start the image capture intent to take photo
        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
       if (resultCode == RESULT_OK) {
         // by this point we have the camera photo on disk
         Bitmap takenImage = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
         // RESIZE BITMAP, see section below
         // Load the taken image into a preview
         ImageView ivPreview = (ImageView) findViewById(R.id.ivPreview);
         ivPreview.setImageBitmap(takenImage);   
       } else { // Result was a failure
    	   Toast.makeText(this, "Picture wasn't taken!", Toast.LENGTH_SHORT).show();
       }
    }
}

style

https://youtu.be/S2V5jlLjwPU

https://code.tutsplus.com/tutorials/android-from-scratch-creating-styles-and-themes–cms-26942

theme

https://youtu.be/3g-HKRJrtnI

shared preference

https://youtu.be/xv_JJbjDQ3M

https://developer.android.com/training/data-storage/shared-preferences

Context context = getActivity();
SharedPreferences sharedPref = context.getSharedPreferences(
       getString(R.string.preference_file_key), Context.MODE_PRIVATE);

writing

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score_key), newHighScore);
editor.commit();

reading

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.integer.saved_high_score_default_key);
int highScore = sharedPref.getInt(getString(R.string.saved_high_score_key), defaultValue);

alt+enter 

필요한 library import 하기

asynctask

다른 thread상에서 작업을 수행해야 하는 경우에 사용한다. 단 지정된 작업이 한번 수행되면 끝나게 된다.

handlerthread

다른 thread상에서 작업을 수행하는데 asynctask와는 다르게 여러개 일련의 작업을 수행할수 있다. handler, looper, message 등을 이용한다.

작업을 지연시키는 방법

Handler.sendMessageDelayed()

Hanlder.postDelayed()를 이용하는 방법

AlarmManager를 이용하는 방법 특정시간후에나 특정되지않은 어느 정도 시간후에 작업수행한다.

PendingIntent를 이용 추후에 PendingIntent의 send()를 호출하여 원하는 때에 작업 수행한다. 

JobScheduler, JobServices를 이용 특정 조건이 만족 되는 때에 작업 수행하게 한다.

Sync Adapter를 이용하는 방법이 있다. 이는 반복적인 네트워크 작업에 적합하다.

services

IntentService : IntentService를 extends하는 service class를 만들고 이를 manifest file에 등록한다. 다른 activity나 fragment에서 액티버티obj.startService(인텐트obj) 를 통해 service작업( background작업 )을 시작하게 한다. 

Service  : activity나 다른 service와 같은 component에 bind되어서 activity, 다른 service에서 service내의 함수에 접근 가능하며 Bound Service라고 불린다. 구현방법에 따라 Binder를 이용한 방법, handler와 messenger를 이용한 방법, AIDL를 이용한 방법이 있다.

service자체에서만 작업흐름을 제어가능하고 즉 service를 시작한 activity, fragment에서는 제어하지 못하는 경우. non-sticky service라고 불린다. 

android animation

ObjectAnimator ( property animator라고도 불린다 )를 이용한 방법

     때때로 시작점과 종료점을 구하는데 도움을 주는 TypeEvaluator를 덧붙여 사용하기도 한다.

     AnimatorSet을 통해 여러개의 animator을 연결, 동시 진행 가능하다.

transformation property 값의 변경을 이용한 방법

    getRotation , setRotation

    getPivotX, setPivotX, getPivotY, setPivotY

    getScaleX, setScaleX, getScaleY, setScaleY

    getTranslationX, setTranslationX, getTranslationY, setTranslationY

android 5.0 lollipop부터 등장한 새로운 animation 구현방법  – material design에 관련된 것들

state list animators, animated state list drawables, circular reveals, shared element transitions