public abstract class BaseActivity extends AppCompatActivity {

protected ProgressDialog mProgressDialog = null;

protected abstract Context getContext();

/**
* 프로그래스를 보여준다.
*/
public void showProgressDialog() {
if (mProgressDialog == null) {
if (Build.VERSION_CODES.KITKAT < Build.VERSION.SDK_INT) {

//             R.style.ProgressDialogStyle은 커스텀으로 정의한 스타일임
mProgressDialog = new ProgressDialog(getNowContext(), R.style.ProgressDialogStyle);

} else {
mProgressDialog = new ProgressDialog(getNowContext());
}
mProgressDialog.setMessage(getString(R.string.progress_message));
mProgressDialog.setIndeterminate(true);
mProgressDialog.setCancelable(false);
}
mProgressDialog.show();
}

/**
* 프로그래스를 숨긴다.
*/
public void hideProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}

}


R.style.ProgressDialogStyle

<style name="ProgressDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:layout_centerVertical">true</item>
<item name="android:layout_centerHorizontal">true</item>
<item name="colorAccent">@color/colorPrimary</item>
</style>


사용 할 때

private class DownloadTask extends AsyncTask{


@Override
protected void onPreExecute() {
showProgressDialog(); // 작업 시작


//작업 준비 코드 작성
super.onPreExecute();
}


@Override
protected Object doInBackground(Object[] params) {
//작업 중
return null;
}

@Override
protected void onPostExecute(Object o) {
//작업 끝 코드 작성

hideProgressDialog(); // 작업 끝
super.onPostExecute(o);
}
}

 이런 느낌으로 사용하시면 됩니다.

728x90
반응형

많은 앱들이 카카오톡 처럼 탭 뷰페이저 형식을 사용합니다.



그래서 간단히 TabLayout + ViewPager + fragment 형식의 앱을 만들어서 공유드립니다.


다음과 같이 만들었는데요 


1. 라이브러리 셋팅


compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.android.support:support-v4:25.2.0'
compile 'com.android.support:recyclerview-v7:25.2.0'
compile 'com.android.support:design:25.2.0'


- AppCompatActivity클래스는 appcompatV7 라이브러리에 포함되어 있습니다.

- ViewPager클래스는 supportV4 라이브러리에 포함되어 있습니다.

- TabLayout은 design 라이브러리에 포함되어 있습니다.

2. 소스코드

MainActivity.java

import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import pe.sk.com.myapplication.R;
import pe.sk.com.myapplication.adapter.MainTabPagerAdapter;
import pe.sk.com.myapplication.data.DummyContent;
import pe.sk.com.myapplication.listener.OnListFragmentInteractionListener;

public class MainActivity extends AppCompatActivity implements OnListFragmentInteractionListener {
private TabLayout mTabLayout = null; // 탭 레이아웃
private ViewPager mViewPager = null; // 뷰 페이저
private MainTabPagerAdapter mPagerAdapter = null; // 탭 어댑터

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabLayout = (TabLayout) findViewById(R.id.main_tab);
mViewPager = (ViewPager) findViewById(R.id.main_viewpager);
mTabLayout.setupWithViewPager(mViewPager);

mPagerAdapter = new MainTabPagerAdapter(getSupportFragmentManager(), this);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(TabLayout.Tab tab) {

}

@Override
public void onTabReselected(TabLayout.Tab tab) {

}
});
}

@Override
public void onListFragmentInteraction(DummyContent.DummyItem item) {
Toast.makeText(this,item.content,Toast.LENGTH_SHORT).show();
}
}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.design.widget.TabLayout
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="@+id/main_tab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#ff880033"
android:minHeight="?attr/actionBarSize"
app:tabIndicatorColor="#bbdefa"
app:tabSelectedTextColor="#ffffff"
app:tabTextColor="#88ffffff"
/>


<android.support.v4.view.ViewPager
android:id="@+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/main_tab"
/>
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>

MainTabPagerAdapter.java


import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

import pe.sk.com.myapplication.R;
import pe.sk.com.myapplication.fragment.FirstFragment;
import pe.sk.com.myapplication.fragment.TwoFragment;

/**
* Created by P092613 on 2017-03-09.
*/

public class MainTabPagerAdapter extends FragmentStatePagerAdapter {
private final static int TAB_COUNT = 2;     // 탭의 개수


private Context mContext;
private FirstFragment mFirstFragment = null;
private TwoFragment mTwoFragment = null;

private int[] mTabTitle = {R.string.first, R.string.two};

public MainTabPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.mContext = context;
}

@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
mFirstFragment = FirstFragment.newInstance(1);
return mFirstFragment;
default:
mTwoFragment = TwoFragment.newInstance(1);
return mTwoFragment;
}
}

@Override
public CharSequence getPageTitle(int position) {
return mContext.getString(mTabTitle[position]);
}

@Override
public int getCount() {
return TAB_COUNT;
}
}


FirstFragment.java 와 TwoFragment.java 코드는 동일함

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import pe.sk.com.myapplication.R;
import pe.sk.com.myapplication.adapter.FirstRecyclerViewAdapter;
import pe.sk.com.myapplication.data.DummyContent;
import pe.sk.com.myapplication.listener.OnListFragmentInteractionListener;

/**
* A fragment representing a list of Items.
* <p/>
* Activities containing this fragment MUST implement the {@link OnListFragmentInteractionListener}
* interface.
*/
public class FirstFragment extends Fragment {

// TODO: Customize parameter argument names
private static final String ARG_COLUMN_COUNT = "column-count";
// TODO: Customize parameters
private int mColumnCount = 1;
private OnListFragmentInteractionListener mListener;

/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public FirstFragment() {
}

// TODO: Customize parameter initialization
@SuppressWarnings("unused")
public static FirstFragment newInstance(int columnCount) {
FirstFragment fragment = new FirstFragment();
Bundle args = new Bundle();
args.putInt(ARG_COLUMN_COUNT, columnCount);
fragment.setArguments(args);
return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (getArguments() != null) {
mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_first_list, container, false);

// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
} else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
}
recyclerView.setAdapter(new FirstRecyclerViewAdapter(DummyContent.ITEMS, mListener));
}
return view;
}


@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (OnListFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnListFragmentInteractionListener");
}
}

@Override
public void onDetach() {
super.onDetach();
mListener = null;
}


}


FirstRecyclerViewAdapter.java 와 TwoRecyclerViewAdapter.java 코드는 동일함


import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

import pe.sk.com.myapplication.R;
import pe.sk.com.myapplication.data.DummyContent.DummyItem;
import pe.sk.com.myapplication.listener.OnListFragmentInteractionListener;

/**
* {@link RecyclerView.Adapter} that can display a {@link DummyItem} and makes a call to the
* specified {@link OnListFragmentInteractionListener}.
* TODO: Replace the implementation with code for your data type.
*/
public class FirstRecyclerViewAdapter extends RecyclerView.Adapter<FirstRecyclerViewAdapter.ViewHolder> {

private final List<DummyItem> mValues;
private final OnListFragmentInteractionListener mListener;

public FirstRecyclerViewAdapter(List<DummyItem> items, OnListFragmentInteractionListener listener) {
mValues = items;
mListener = listener;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_first, parent, false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).id);
holder.mContentView.setText(mValues.get(position).content);

holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mListener) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onListFragmentInteraction(holder.mItem);
}
}
});
}

@Override
public int getItemCount() {
return mValues.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public DummyItem mItem;

public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
}

@Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}


fragment_first_list.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
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:id="@+id/list"
android:name="pe.sk.com.myapplication.fragment.FirstItemFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context="pe.sk.com.myapplication.fragment.FirstFragment"
tools:listitem="@layout/fragment_first"/>


fragment_first.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:id="@+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"/>

<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"/>
</LinearLayout>


728x90
반응형

간혹 안드로이드 스튜디오를 실행해보면 다음과 같은 오류를 만날 수 있습니다.

Error:Unable to start the daemon process.

This problem might be caused by incorrect configuration of the daemon.

For example, an unrecognized jvm option is used.

Please refer to the user guide chapter on the daemon at https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html

Please read the following process output to find out more:

-----------------------

Error occurred during initialization of VM

Could not reserve enough space for 1572864KB object heap



이럴 경우 당황하지 말고 

gradle.properties 파일로 들어가서 Xmx1536m -> Xmx512m 으로 변경해준다.

저장 후 상단 오른쪽에 Try again을 눌러주면 끝

728x90
반응형

개발을 하다보면 이러한 오류를 만날 수 있습니다.

이럴때는 당황하지 말고

Poject의 build.gradle에 compile 'com.android.support:design:25.2.0' lib를 추가하시면 해결 됩니다.





728x90
반응형

뷰페이저를 사용중에 특정 페이지만 툴바메뉴가 보였으면 좋겠다고 하는 미치광이들이 아주 간혹 있습니다.


이런 미치광이들을 상대하는 개발자들을 위해 공유드립니다


                                        


1번1번  2번





우선 findViewById메서드로 Toolbar객체 DrawerLayout객체를 만들어 줍니다.

/**
* 1번 좌측메뉴, 좌측슬라이드 노출되도록 설정
*/
protected void setToolbarVisibleLeftMenu() {
if (mToolbar != null && mDrawerLayout != null) {
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(true);
// 상단 툴바를 이용하여 좌측 메뉴 열기 / 닫기 설정
mActionBarDrawerToggle = new ActionBarDrawerToggle((Activity) getNowContext(), mDrawerLayout, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
// Drawer Toggle Object Made
mDrawerLayout.setDrawerListener(mActionBarDrawerToggle); // Drawer Listener set to the Drawer toggle
mActionBarDrawerToggle.syncState();
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
}

/**
* 2번 좌측메뉴, 좌측슬라이드 노출되지않도록 설정
*/
protected void setToolbarGoneLeftMenu() {
if (mToolbar != null && mDrawerLayout != null) {
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(false);
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}
}


728x90
반응형

안드로이드는 다음과 같이 휠을 날짜나 시간, 숫자만 제공해줍니다.


  





글자(String)가 쓰여진 휠뷰는 안드로이드 자체적으로 제공해 주지 않습니다. 그래서 lib를 써야합니다.

많은  lib들이 있지만 그중에 가장 괜찮고 안정성 있는 lib라고 생각되어 소개합니다.



Github 주소

https://github.com/maarek/android-wheel





Demo


@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);


setContentView(R.layout.cities_layout);

String[] locationData= new String[]{"남산", "대구", "부산", "인천", "경주", "안산", "서울", "광주", "충주", "강원"};



WheelView country = (WheelView) findViewById(R.id.country);


  // Cyclic 여부 true일경우 위아래로 값이 생겨서 무제한 스크롤 가능(직접 해보시길 설명을 못하겟음) 

country.setCyclic(false);

country.setCurrentItem(0); // position 설정 혹은 index 설정

country.setVisibleItems(3); // 보여줄 item의 개수(테스트 결과 이 함수는 적용되지 않는다.)

ArrayWheelAdapter<String> adapter = new ArrayWheelAdapter<String>(this, locationData);

adapter.setTextSize(30); // 글씨 크기

country.setViewAdapter(adapter); //어댑터를 설정한다.

country.addScrollingListener( new OnWheelScrollListener() {

@Override

public void onScrollingStarted(WheelView wheel) {

// 스크롤 시작

scrolling = true;

}

@Override

public void onScrollingFinished(WheelView wheel) {

// 스크롤 끝

scrolling = false;

}

});

}




이슈사항


- 아래 그림의 휠 두개는 서로 연동 됩니다. 예를 들어 지역 휠을 컨트롤 하여 "남산"을 선택 시 층은 11층까지 보이도록 갱신됩니다.

 앞에 설명과 같이 지역 휠을 컨트롤 하여 "부산"을 선택 시 1층만 보이도록 갱신됩니다.

ex)

남산 - 1,2,3,4,5,6,7,8,9,10,11층

대구 - 1,2,3층

부산 - 1층

인천 - 1,2,3,4,5,6층

   .

   .

   .



-휠을 두개 쓸 경우 층 휠을 맨 밑으로 내리고 바로 지역 휠을 스크롤 할 경우 층 휠의 층수가 보이지 않는 이슈가 있습니다.




해결방법

-완벽한 해결 방법은 아니지만 onScrollingStarted콜백이 호출 될때마다 층휠을 setCurrentItem(0);으로 초기화 해주면 해당이슈사항은 해결 됩니다. 

728x90
반응형

안드로이드에서는 키보드가 올라가고 내려갈때 콜백 이벤트 필요한 순간이 있을때


이 코드를 사용하시면 됩니다.


우선 구글링으로 찾은 이곳에서 SoftKeyboard 클래스의 용도를 확인합니다.


https://felhr85.net/2014/05/04/catch-soft-keyboard-showhidden-events-in-android/


안에 들어가 보시면 It is available here. 이라고 쓰인 곳을 누르면 SoftKeyboard.java를 다운받을 수 있도록 안내해 줍니다.


SoftKeyboard.java를 다운받고 프로젝트에 넣고 아래 소스를 넣어 줍니다.


TestAct.java


package com.example.testline;


import android.app.Activity;

import android.app.Service;

import android.os.Bundle;

import android.os.Handler;

import android.os.Looper;

import android.view.inputmethod.InputMethodManager;

import android.widget.LinearLayout;


public class TestAct extends Activity {

SoftKeyboard mSoftKeyboard;

LinearLayout mLlEdit;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);


mLlEdit = (LinearLayout) findViewById(R.id.ll_edit);


InputMethodManager controlManager = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);

mSoftKeyboard = new SoftKeyboard(mLlEdit, controlManager);

mSoftKeyboard.setSoftKeyboardCallback(new SoftKeyboard.SoftKeyboardChanged() {

@Override

public void onSoftKeyboardHide() {

new Handler(Looper.getMainLooper())

.post(new Runnable() {

@Override

public void run() {

// 키보드 내려왔을때

}

});

}


@Override

public void onSoftKeyboardShow() {

new Handler(Looper.getMainLooper())

.post(new Runnable() {

@Override

public void run() {

// 키보드 올라왔을때

}

});

}

});


}


@Override

public void onDestroy() {

super.onDestroy();

mSoftKeyboard.unRegisterSoftKeyboardCallback();

}


}



activity_main.xml 파일


     <LinearLayout

        android:id="@+id/ll_edit"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:focusable="true"

        android:focusableInTouchMode="true"

        android:orientation="horizontal" >

<TextView

          android:layout_width="80dp"

          android:layout_height="41.33dp"

          android:gravity="center_vertical"

          android:text="@string/visit_floor"

          android:textColor="@android:color/black"

          android:textSize="16.67sp" />


      <EditText

          android:id="@+id/EditText"

          android:layout_width="fill_parent"

          android:layout_height="41.33dp"

          android:layout_gravity="center"

          android:gravity="center"

          android:inputType="textAutoComplete"

          android:textSize="16.67sp" />

  </LinearLayout>


SoftKeyboard.java


728x90
반응형

일반적인 String 스피너 만들기


- SpinnerActivity.java


public class SpinnerActivity extends BaseActivity {

private String[] mCategoryArr = null;
private Spinner mSubjectSpinner = null;
private String mSelectCategory = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.spinner_activity);
initView();
}


private void initView() {
mSubjectSpinner = (Spinner) findViewById(R.id.subject_spinner);
mSubjectSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
switch (position) {
case 0:
mSelectCategory = mCategoryArr[0];
break;

case 1:
mSelectCategory = mCategoryArr[1];
break;

case 2:
mSelectCategory = mCategoryArr[2];
break;

}

}


@Override
public void onNothingSelected(AdapterView<?> adapterView) {

}

});

}

private void settingView() {
mCategoryArr = getResources().getStringArray(R.array.subject_array);
mSelectCategory = mCategoryArr[0];
ArrayAdapter<CharSequence> spinnerLargerAdapter = ArrayAdapter.createFromResource(this, R.array.subject_array, R.layout.spinner_item);
mSubjectSpinner.setAdapter(spinnerLargerAdapter);
mSubjectSpinner.setSelection(0);
}
}



R.layout.spinner_activity.xml

#저 같은 경우 @drawable/ic_keyboard_arrow_down_black_24dp을 drawable-hdpi폴더에만 넣어놨습니다.


<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="vertical">


<Spinner
android:id="@+id/free_subject_spinner"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginRight="10dp"
android:background="@drawable/ic_keyboard_arrow_down_black_24dp"
/>
</LinearLayout>



R.layout.spinner_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="@+id/spinner_title"
android:layout_height="50dp"
android:paddingLeft="14.62dp"
android:textSize="16dp"
android:textColor="@color/black_color"
android:singleLine="true"
android:ellipsize="marquee"
android:background="@drawable/custom_menu_item_bg"
android:gravity="center_vertical"/>




res\drawable\custom_menu_item_bg.xml


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#e6e6e6"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
</selector>



res\values\arrays.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="subject_array">
<item>[건의]</item>
<item>[후기]</item>
<item>[기타]</item>
</string-array>
</resources>




728x90
반응형

'Android' 카테고리의 다른 글

안드로이드 WheelView or StringPicker  (0) 2017.03.03
안드로이드 키보드 이벤트  (0) 2017.02.23
안드로이드 액티비티 애니메이션  (0) 2016.11.14
RecyclerView 만들기  (0) 2016.11.14
Activity와 Fragment간 데이터 전달  (0) 2016.11.14

+ Recent posts