Android

겜팔이의 안드로이드 세뇌교실 (안드로이드)

  1. 액티비티
  2. 인텐트
  3. 뷰 – Widget, Layout, Event
  4. Fragment
  5. ViewPager, TabLayout
  6. SharedPreferences
  7. 동적 뷰 생성 (ArrayList 이용)
  8. RecyclerView
  9. Thread, Log
  10. Glide
  11. 서버-클라이언트, Okhttp, JSON
  12. 카메라
  13. 최종 10강 완결 소스
  14. UUID 사용

 

 

https://www.youtube.com/playlist?list=PLG9ohJAOA2PBtTBlGkmzk6_MuaUQBg_pw

 

 

https://github.com/g82/Anstagram/releases

 

 

액티비티

 

윈도우의 창과 같음.

UI를 보여주고, 행동도 함.

 

package com.example.mytestapp1;

 

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

 

public class MainActivity extends AppCompatActivity {

 

public static final String TAG = “MainActivity”;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

 

@Override

protected void onStart() {

super.onStart();

Log.d(TAG, “onStart”);

}

 

@Override

protected void onResume() {

super.onResume();

Log.d(TAG, “onResume”);

}

 

@Override

protected void onPause() {

super.onPause();

Log.d(TAG, “onPause”);

}

 

@Override

protected void onStop() {

super.onStop();

Log.d(TAG, “onStop”);

}

 

@Override

protected void onDestroy() {

super.onDestroy();

Log.d(TAG, “onDestroy”);

}

}

 

 

 

 

 

인텐트

 

 

액티비티는 인텐트를 통해서 의사소통을 함

인텐트는 우편배달부

1. 액티비티 – 액티비티(서비스, Broadcast Receiver);

2. 앱 – 앱

3. 편지부터 택배까지 배달해주는 우편 배달부

 

명시적 인텐트 (보낸이와 받는이를 명시)

Intent intent = new Intent(this, NewActivity.class);

startActivity(intent)

 

암시적 인텐트 (앱 밖에서, 앱과 앱 사이에서)

Intent sendIntent = new Intent();

sendIntent.setAction(Intent.ACTION_CALL);

startActivity(sendIntent);

 

인텐트를 통해서 특정 액티비티에 메시지 보내기

보내는 측: intent.putExtra(“intent-message”,”메시지를 보냅니다.”);

받는 측: String message = getIntent().getStringExtra(“intent-message”);

 

MainActivity.java

 

package com.example.mytestapp1;

 

import android.content.Intent;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.Toast;

 

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

Button button = findViewById(R.id.btn_call);

button.setOnClickListener(this);

}

 

@Override

public void onClick(View v) {

 

Toast.makeText(MainActivity.this, “클릭!!”, Toast.LENGTH_SHORT).show();

 

/* 암시적 액티비티

Intent intent = new Intent();

intent.setAction(Intent.ACTION_DIAL);

startActivity(intent);

*/

 

// 명시적 액티비티

Intent intent = new Intent(MainActivity.this, CallActivity.class);

intent.putExtra(“intent-message”,”메시지를 보냅니다.”);

startActivity(intent);

}

}

 

<?xml version=”1.0″ encoding=”utf-8″?>

<RelativeLayout 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=”.MainActivity”>

 

<Button

android:text=”CALL”

android:id=”@+id/btn_call”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

</RelativeLayout>

 

 

CallActivity.java

 

package com.example.mytestapp1;

 

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.Toast;

 

public class CallActivity extends AppCompatActivity {

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_call);

String message = getIntent().getStringExtra(“intent-message”);

 

Toast.makeText(this, message, Toast.LENGTH_SHORT).show();

}

}

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout 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=”.CallActivity”>

 

<TextView

android:textSize=”36sp”

android:text=”CALL”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

</LinearLayout>

 

 

 

 

 

뷰 – Widget, Layout, Event

 

 

MainActivity.java

 

package com.example.mytestapp2layout;

 

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.MotionEvent;

import android.view.View;

import android.widget.TextView;

import android.widget.Toast;

 

public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener {

 

TextView tv;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

findViewById(R.id.iv_like).setOnClickListener(this);

findViewById(R.id.iv_share).setOnClickListener(this);

findViewById(R.id.iv_photo).setOnTouchListener(this);

findViewById(R.id.iv_photo).setOnClickListener(this);

}

 

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.iv_like:

Toast.makeText(this, “좋아요 강예원”, Toast.LENGTH_SHORT).show();

break;

case R.id.iv_share:

Toast.makeText(this, “공유 강예원”, Toast.LENGTH_SHORT).show();

break;

case R.id.iv_photo:

Toast.makeText(this, “클릭 강예원”, Toast.LENGTH_SHORT).show();

break;

}

}

 

@Override

public boolean onTouch(View v, MotionEvent event) {

 

Toast.makeText(this, “터치 강예원.”, Toast.LENGTH_SHORT).show();

 

switch (event.getAction()) {

 

case MotionEvent.ACTION_UP:

Toast.makeText(this, “터치 업”, Toast.LENGTH_SHORT).show();

break;

case MotionEvent.ACTION_DOWN:

Toast.makeText(this, “터치 다운”, Toast.LENGTH_SHORT).show();

break;

}

return false;

}

}

 

 

 

activity_main.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout 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”

android:orientation=”vertical”

tools:context=”.MainActivity”>

 

<LinearLayout

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:text=”Hello World!”

android:weightSum=”2″>

 

<TextView

android:layout_width=”0dp”

android:layout_height=”wrap_content”

android:paddingTop=”16dp”

android:paddingBottom=”16dp”

android:textSize=”24sp”

android:text=”Timeline”

android:gravity=”center”

android:layout_weight=”1″/>

 

<TextView

android:layout_width=”0dp”

android:layout_height=”wrap_content”

android:paddingTop=”16dp”

android:paddingBottom=”16dp”

android:textSize=”24sp”

android:text=”Untitled”

android:gravity=”center”

android:layout_weight=”1″/>

 

</LinearLayout>

 

<View

android:layout_width=”match_parent”

android:layout_height=”2px”

android:background=”#000000″ />

 

<ScrollView

android:layout_width=”match_parent”

android:layout_height=”match_parent”>

 

<LinearLayout

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:orientation=”vertical”>

 

<include layout=”@layout/item_post” />

<include layout=”@layout/item_post” />

<include layout=”@layout/item_post” />

<include layout=”@layout/item_post” />

<include layout=”@layout/item_post” />

 

</LinearLayout>

 

</ScrollView>

</LinearLayout>

 

 

 

item_post.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:orientation=”vertical”>

 

<ImageView

android:id=”@+id/iv_photo”

android:layout_width=”match_parent”

android:layout_height=”300dp”

android:scaleType=”centerCrop”

android:src=”@drawable/kanghyewon” />

 

<RelativeLayout

android:paddingTop=”8dp”

android:paddingLeft=”16dp”

android:paddingRight=”16dp”

android:paddingBottom=”8dp”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”>

 

<ImageView

android:id=”@+id/iv_like”

android:layout_width=”24dp”

android:layout_height=”24dp”

android:background=”#454522″ />

 

<TextView

android:id=”@+id/tv_desc”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_centerVertical=”true”

android:layout_marginLeft=”8dp”

android:layout_marginRight=”8dp”

android:lines=”1″

android:layout_toLeftOf=”@+id/iv_share”

android:layout_toStartOf=”@id/iv_share”

android:layout_toEndOf=”@id/iv_like”

android:layout_toRightOf=”@id/iv_like”

android:ellipsize=”end”

android:text=”안녕하세요. 아이즈원 강혜원입니다. 반갑습니다.” />

 

<ImageView

android:id=”@+id/iv_share”

android:layout_alignParentRight=”true”

android:layout_alignParentEnd=”true”

android:background=”#764432″

android:layout_width=”48px”

android:layout_height=”48px” />

</RelativeLayout>

 

<View

android:layout_width=”match_parent”

android:layout_height=”1px”

android:background=”#000000″ />

 

<RelativeLayout

android:padding=”16dp”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”>

 

<TextView

android:id=”@+id/tv_uploader”

android:text=”ansta_”

android:lines=”1″

android:maxLength=”10″

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

<TextView

android:layout_marginLeft=”8dp”

android:layout_marginStart=”8dp”

android:layout_toRightOf=”@id/tv_uploader”

android:layout_toEndOf=”@id/tv_uploader”

android:layout_alignParentRight=”true”

 

android:text=”불꽃놀이했어요! :)”

android:lines=”1″

android:maxLength=”10″

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

</RelativeLayout>

 

</LinearLayout>

 

 

 

 

 

Fragment

 

Mainactivity.java

 

package com.example.mytestappfragment;

 

import android.support.v4.app.Fragment;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

 

public class MainActivity extends AppCompatActivity implements OnColorButtonListener {

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

GreenFragment greenFragment = new GreenFragment();

 

getSupportFragmentManager().beginTransaction()

.add(R.id.fl_right, greenFragment);

}

 

@Override

public void onColorClick(int color) {

Fragment fragment = null;

 

switch (color) {

case 0:

fragment = new RedFragment();

break;

case 1:

fragment = new GreenFragment();

break;

case 2:

fragment = new BlueFragment();

break;

}

 

getSupportFragmentManager().beginTransaction()

.replace(R.id.fl_right, fragment).commit();

}

}

 

 

 

OnColorButtonListener.java

 

package com.example.mytestappfragment;

 

public interface OnColorButtonListener {

void onColorClick(int color);

}

 

 

 

LeftFragment.java

 

package com.example.mytestappfragment;

 

 

import android.content.Context;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

 

/**

* A simple {@link Fragment} subclass.

*/

public class LeftFragment extends Fragment implements View.OnClickListener {

 

private OnColorButtonListener onColorButtonListener;

 

@Override

public void onAttach(Context context) {

super.onAttach(context);

onColorButtonListener = (OnColorButtonListener) context;

}

 

public LeftFragment() {

// Required empty public constructor

}

 

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

 

View view = inflater.inflate(R.layout.fragment_left, container, false);

view.findViewById(R.id.v_red).setOnClickListener(this);

view.findViewById(R.id.v_green).setOnClickListener(this);

view.findViewById(R.id.v_blue).setOnClickListener(this);

return view;

}

 

@Override

public void onClick(View v) {

 

switch (v.getId()) {

case R.id.v_red:

onColorButtonListener.onColorClick(0);

break;

case R.id.v_green:

onColorButtonListener.onColorClick(1);

break;

case R.id.v_blue:

onColorButtonListener.onColorClick(2);

break;

}

}

}

 

 

 

RedFragment.java

 

package com.example.mytestappfragment;

 

import android.os.Bundle;

import android.support.annotation.NonNull;

import android.support.annotation.Nullable;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

public class RedFragment extends Fragment {

 

@Nullable

@Override

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_red, null);

}

}

 

 

 

GreenFragment.java

 

package com.example.mytestappfragment;

 

import android.os.Bundle;

import android.support.annotation.NonNull;

import android.support.annotation.Nullable;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

public class GreenFragment extends Fragment {

 

@Nullable

@Override

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_green, null);

}

}

 

 

 

BlueFragment.java

package com.example.mytestappfragment;

 

import android.os.Bundle;

import android.support.annotation.NonNull;

import android.support.annotation.Nullable;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

public class BlueFragment extends Fragment {

 

@Nullable

@Override

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_blue, null);

}

}

 

 

 

 

activity_main.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout 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=”.MainActivity”>

 

<fragment

android:id=”@+id/fragment_left”

android:name=”com.example.mytestappfragment.LeftFragment”

android:background=”#ffe873″

android:layout_weight=”1″

android:layout_width=”0dp”

android:layout_height=”match_parent” />

 

<FrameLayout

android:id=”@+id/fl_right”

android:layout_weight=”2″

android:layout_width=”0dp”

android:layout_height=”match_parent” />

 

 

 

</LinearLayout>

 

 

 

fragment_left.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<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=”.LeftFragment”>

 

<!– TODO: Update blank fragment layout –>

<View

android:id=”@+id/v_red”

android:background=”#ff8174″

android:layout_weight=”1″

android:layout_width=”match_parent”

android:layout_height=”0dp” />

 

<View

android:id=”@+id/v_green”

android:background=”#6ed168″

android:layout_weight=”1″

android:layout_width=”match_parent”

android:layout_height=”0dp” />

 

<View

android:id=”@+id/v_blue”

android:background=”#4c9afa”

android:layout_weight=”1″

android:layout_width=”match_parent”

android:layout_height=”0dp” />

 

</LinearLayout>

 

 

 

fragment_red.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:orientation=”vertical” android:layout_width=”match_parent”

android:background=”#ff8174″

android:layout_height=”match_parent”>

 

</LinearLayout>

 

 

 

fragment_green.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:orientation=”vertical” android:layout_width=”match_parent”

android:background=”#6ed168″

android:layout_height=”match_parent”>

 

</LinearLayout>

 

 

 

fragment_blue.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:orientation=”vertical” android:layout_width=”match_parent”

android:background=”#4c9afa”

android:layout_height=”match_parent”>

 

</LinearLayout>

 

 

 

 

 

ViewPager, TabLayout

 

 

MainActivity.java

 

package com.example.mytestappviewpager;

 

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentPagerAdapter;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

 

public class MainActivity extends AppCompatActivity {

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

TabLayout tabLayout = findViewById(R.id.tl_tabs);

ViewPager viewPager = findViewById(R.id.vp_pager);

 

Fragment[] arrFragments = new Fragment[3];

arrFragments[0] = new RedFragment();

arrFragments[1] = new YellowFragment();

arrFragments[2] = new GreenFragment();

 

MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager(), arrFragments);

viewPager.setAdapter(adapter);

tabLayout.setupWithViewPager(viewPager);

}

 

private class MyPagerAdapter extends FragmentPagerAdapter {

 

private Fragment[] arrFragments;

 

public MyPagerAdapter(FragmentManager fm, Fragment[] arrFragments) {

super(fm);

this.arrFragments = arrFragments;

}

 

@Override

public Fragment getItem(int i) {

return arrFragments[i];

}

 

@Override

public int getCount() {

return arrFragments.length;

}

 

@Nullable

@Override

public CharSequence getPageTitle(int position) {

switch (position) {

case 0:

return “RED”;

case 1:

return “YELLOW”;

case 2:

return “GREEN”;

default:

return  “”;

}

}

}

}

 

 

 

 

RedFragment.java

 

package com.example.mytestappviewpager;

 

 

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

 

/**

* A simple {@link Fragment} subclass.

*/

public class RedFragment extends Fragment {

 

public RedFragment() {

// Required empty public constructor

}

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

return inflater.inflate(R.layout.fragment_red, container, false);

}

}

 

 

 

 

YellowFragment.java

 

package com.example.mytestappviewpager;

 

 

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

 

/**

* A simple {@link Fragment} subclass.

*/

public class YellowFragment extends Fragment {

 

 

public YellowFragment() {

// Required empty public constructor

}

 

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

return inflater.inflate(R.layout.fragment_yellow, container, false);

}

}

 

 

 

 

GreenFragment.java

 

package com.example.mytestappviewpager;

 

 

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

 

/**

* A simple {@link Fragment} subclass.

*/

public class GreenFragment extends Fragment {

 

 

public GreenFragment() {

// Required empty public constructor

}

 

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

return inflater.inflate(R.layout.fragment_green, container, false);

}

}

 

 

 

 

 

activity_main.xml

 

implementation ‘com.android.support:design:28.0.0’

 

 

<?xml version=”1.0″ encoding=”utf-8″?>

<RelativeLayout 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=”.MainActivity”>

 

<android.support.design.widget.TabLayout

android:id=”@+id/tl_tabs”

android:layout_width=”match_parent”

android:layout_height=”wrap_content” />

 

<android.support.v4.view.ViewPager

android:id=”@+id/vp_pager”

android:layout_below=”@id/tl_tabs”

android:layout_width=”match_parent”

android:layout_height=”match_parent” />

 

</RelativeLayout>

 

 

 

 

fragment_red.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<FrameLayout 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:background=”#ea4e00″

tools:context=”.RedFragment”>

 

<!– TODO: Update blank fragment layout –>

<TextView

android:layout_width=”match_parent”

android:layout_height=”match_parent”

android:text=”@string/hello_blank_fragment” />

 

</FrameLayout>

 

 

 

 

fragment_yellow.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<FrameLayout 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:background=”#fdff7a”

tools:context=”.YellowFragment”>

 

<!– TODO: Update blank fragment layout –>

<TextView

android:layout_width=”match_parent”

android:layout_height=”match_parent”

android:text=”@string/hello_blank_fragment” />

 

</FrameLayout>

 

 

 

 

fragment_green.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<FrameLayout 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:background=”#80cf00″

tools:context=”.GreenFragment”>

 

<!– TODO: Update blank fragment layout –>

<TextView

android:layout_width=”match_parent”

android:layout_height=”match_parent”

android:text=”@string/hello_blank_fragment” />

 

</FrameLayout>

 

 

 

 

 

 

SharedPreferences

 

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

 

MainActivity.java

 

package com.example.mytestappsharedpreference;

 

import android.content.Context;

import android.content.SharedPreferences;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.widget.TextView;

 

public class MainActivity extends AppCompatActivity {

 

public static final String SHARED_PREF_FIRST_USER_KEY = “1000”;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

TextView tv_hello = findViewById(R.id.tv_hello);

 

SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);

int firstUser = sharedPref.getInt(SHARED_PREF_FIRST_USER_KEY, -1);

 

if (firstUser == 1) {

tv_hello.setText(getString(R.string.hello_user));

} else if (firstUser == -1) {

tv_hello.setText(getString(R.string.hello_first));

saveUserIsNotFirst();

}

}

 

private void saveUserIsNotFirst() {

SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);

SharedPreferences.Editor editor = sharedPref.edit();

editor.putInt(SHARED_PREF_FIRST_USER_KEY, 1);

editor.commit();

}

}

 

 

 

activity_main.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<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”

tools:context=”.MainActivity”>

 

<TextView

android:id=”@+id/tv_hello”

android:gravity=”center”

android:layout_width=”match_parent”

android:layout_height=”match_parent”

android:text=”Hello World!”

android:textSize=”36sp” />

 

</RelativeLayout>

 

 

 

strings.xml

 

<resources>

<string name=”app_name”>MyTestAppSharedPreference</string>

<string name=”hello_user”>RE-Hi, Hogangnim.</string>

<string name=”hello_first”>Nice to meet you, Gogaeknim</string>

</resources>

 

 

 

strings.xml (ko)

 

<?xml version=”1.0″ encoding=”utf-8″?>

<resources>

<string name=”app_name”>MyTestAppSharedPreference</string>

<string name=”hello_user”>다시 안녕. 호갱님</string>

<string name=”hello_first”>만나서 반갑습니다. 고객님.</string>

</resources>

 

 

 

 

 

동적 뷰 생성 (ArrayList 이용)

 

 

ArrayList<> : 클래스 이용

List<> : 인터페이스 이용

 

model/PostItem.java

 

package com.example.mytestappdynamicview.model;

 

public class PostItem {

 

boolean isUserLike;

int postLikeCount;

String userName;

String postImgUrl;

String postText;

 

public PostItem(boolean isUserLike, int postLikeCount, String userName, String postImgUrl, String postText) {

this.isUserLike = isUserLike;

this.postLikeCount = postLikeCount;

this.userName = userName;

this.postImgUrl = postImgUrl;

this.postText = postText;

}

 

public boolean isUserLike() {

return isUserLike;

}

 

public int getPostLikeCount() {

return postLikeCount;

}

 

public String getUserName() {

return userName;

}

 

public String getPostImgUrl() {

return postImgUrl;

}

 

public String getPostText() {

return postText;

}

}

 

 

 

MainActivity.java

 

package com.example.mytestappdynamicview;

 

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.LinearLayout;

import android.widget.TextView;

 

import com.example.mytestappdynamicview.model.PostItem;

 

import java.util.ArrayList;

 

public class MainActivity extends AppCompatActivity {

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

ArrayList<PostItem> listItem = new ArrayList<>();

LinearLayout llScrollParent = findViewById(R.id.ll_scroll);

 

for (int i = 0; i < 50; i++) {

PostItem item = new PostItem(

true, 125, “KANGHYEWON”,

“http://www.liveen.co.kr/news/photo/201810/234137_285936_1452.jpg”,

“wow!!!”

);

listItem.add(i, item);

}

 

for (PostItem item : listItem) {

View v = View.inflate(this, R.layout.post_item, null);

TextView tvUserName = v.findViewById(R.id.tv_UserName);

TextView tvPostText = v.findViewById(R.id.tv_PostText);

 

tvUserName.setText(item.getUserName());

tvPostText.setText(item.getPostText());

 

llScrollParent.addView(v);

}

}

}

 

 

 

post_item.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:orientation=”horizontal” android:layout_width=”match_parent”

android:padding=”16dp”

android:layout_height=”wrap_content”>

 

<TextView

android:textColor=”#6200ea”

android:text=”ansta_”

android:id=”@+id/tv_UserName”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

<TextView

android:layout_marginLeft=”8dp”

android:text=”불꽃놀이했어요~~”

android:id=”@+id/tv_PostText”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

</LinearLayout>

 

 

 

 

activity_main.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<ScrollView 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”

tools:context=”.MainActivity”>

 

<LinearLayout

android:id=”@+id/ll_scroll”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:orientation=”vertical” />

 

</ScrollView>

 

 

 

RecyclerView

 

 

model/PostItem.java

 

package com.example.mytestappdynamicview.model;

 

public class PostItem {

 

boolean isUserLike;

int postLikeCount;

String userName;

String postImgUrl;

String postText;

 

public PostItem(boolean isUserLike, int postLikeCount, String userName, String postImgUrl, String postText) {

this.isUserLike = isUserLike;

this.postLikeCount = postLikeCount;

this.userName = userName;

this.postImgUrl = postImgUrl;

this.postText = postText;

}

 

public boolean isUserLike() {

return isUserLike;

}

 

public int getPostLikeCount() {

return postLikeCount;

}

 

public String getUserName() {

return userName;

}

 

public String getPostImgUrl() {

return postImgUrl;

}

 

public String getPostText() {

return postText;

}

}

 

 

 

 

recyclerview/PostAdapter.java

 

package com.example.mytestappdynamicview.recyclerview;

 

import android.content.Context;

import android.support.annotation.NonNull;

import android.support.v7.widget.RecyclerView;

import android.view.View;

import android.view.ViewGroup;

import android.widget.Toast;

 

import com.example.mytestappdynamicview.R;

import com.example.mytestappdynamicview.model.PostItem;

 

import java.util.ArrayList;

 

public class PostAdapter extends RecyclerView.Adapter<PostViewHolder> {

 

private Context mContext;

private  ArrayList<PostItem> postItems;

 

public PostAdapter(Context context, ArrayList<PostItem> listItem) {

this.mContext = context;

postItems = listItem;

}

 

@NonNull

@Override

public PostViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

View baseView = View.inflate(mContext, R.layout.post_item, null);

PostViewHolder postViewHolder = new PostViewHolder(baseView, this);

return postViewHolder;

}

 

@Override

public void onBindViewHolder(@NonNull PostViewHolder holder, int i) {

PostItem item = postItems.get(i);

holder.tvUserName.setText(item.getUserName());

holder.tvPostText.setText(item.getPostText());

holder.tvLikeCount.setText(String.valueOf(item.getPostLikeCount()));

holder.ivImg.setImageResource(R.drawable.khw);

}

 

@Override

public int getItemCount() {

return postItems.size();

}

 

public void onLikeClicked(int position) {

PostItem item = postItems.get(position);

Toast.makeText(mContext, position + ” : ” + item.getPostText(), Toast.LENGTH_SHORT).show();

}

}

 

 

 

recyclerview/PostViewHolder.java

 

package com.example.mytestappdynamicview.recyclerview;

 

import android.support.annotation.NonNull;

import android.support.v7.widget.RecyclerView;

import android.view.View;

import android.widget.CheckBox;

import android.widget.ImageView;

import android.widget.TextView;

 

import com.example.mytestappdynamicview.R;

 

public class PostViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

 

public CheckBox cbLike;

public ImageView ivImg, ivShare;

public TextView tvLikeCount, tvUserName, tvPostText;

private  PostAdapter mAdapter;

 

public PostViewHolder(@NonNull View itemView, PostAdapter postAdapter) {

super(itemView);

mAdapter = postAdapter;

ivImg = itemView.findViewById(R.id.iv_img);

cbLike = itemView.findViewById(R.id.cb_like);

ivShare = itemView.findViewById(R.id.iv_share);

tvLikeCount = itemView.findViewById(R.id.tv_likecount);

tvUserName = itemView.findViewById(R.id.tv_username);

tvPostText = itemView.findViewById(R.id.tv_posttext);

 

cbLike.setOnClickListener(this);

ivShare.setOnClickListener(this);

}

 

@Override

public void onClick(View v) {

 

int position = getAdapterPosition();

Boolean b =  cbLike.isChecked();

 

switch (v.getId()) {

case R.id.cb_like:

mAdapter.onLikeClicked(position);

break;

case R.id.iv_share:

break;

}

}

}

 

 

 

 

MainActivity.java

 

package com.example.mytestappdynamicview;

 

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.support.v7.widget.LinearLayoutManager;

import android.support.v7.widget.RecyclerView;

import android.view.View;

import android.widget.LinearLayout;

import android.widget.TextView;

 

import com.example.mytestappdynamicview.model.PostItem;

import com.example.mytestappdynamicview.recyclerview.PostAdapter;

 

import java.util.ArrayList;

 

public class MainActivity extends AppCompatActivity {

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

ArrayList<PostItem> listItem = new ArrayList<>();

RecyclerView rvList = findViewById(R.id.rv_list);

 

for (int i = 0; i < 50; i++) {

PostItem item = new PostItem(

true, 125, “KANGHYEWON”,

“http://www.liveen.co.kr/news/photo/201810/234137_285936_1452.jpg”,

“wow!!!”

);

listItem.add(i, item);

}

 

PostAdapter adapter = new PostAdapter(this, listItem);

rvList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

rvList.setAdapter(adapter);

}

}

 

 

 

 

drawable/like_button.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<selector xmlns:android=”http://schemas.android.com/apk/res/android”>

<item android:state_checked=”true” android:drawable=”@drawable/btn_on” />

<item android:state_checked=”false” android:drawable=”@drawable/btn_off” />

</selector>

 

 

 

 

layout/activity_main.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<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”

tools:context=”.MainActivity”>

 

<android.support.v7.widget.RecyclerView

android:id=”@+id/rv_list”

android:layout_width=”match_parent”

android:layout_height=”match_parent” />

 

</RelativeLayout>

 

 

 

 

layout/post_item.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:orientation=”vertical” android:layout_width=”match_parent”

android:layout_height=”wrap_content”>

 

<ImageView

android:id=”@+id/iv_img”

android:background=”#424242″

android:scaleType=”fitCenter”

android:layout_width=”match_parent”

android:layout_height=”300dp” />

 

<RelativeLayout

android:paddingTop=”8dp”

android:paddingBottom=”8dp”

android:paddingLeft=”16dp”

android:paddingRight=”16dp”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”>

 

<CheckBox

android:button=”@drawable/like_button”

android:id=”@+id/cb_like”

android:layout_centerVertical=”true”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

<!–        <ImageView

android:background=”#d50000″

android:id=”@+id/iv_like”

android:layout_width=”24dp”

android:layout_height=”24dp” />–>

 

<TextView

android:id=”@+id/tv_likecount”

android:layout_marginLeft=”8dp”

android:layout_centerVertical=”true”

android:layout_toRightOf=”@id/cb_like”

android:text=”1234″

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

<ImageView

android:layout_alignParentRight=”true”

android:background=”#181818″

android:id=”@+id/iv_share”

android:layout_width=”24dp”

android:layout_height=”24dp” />

 

</RelativeLayout>

 

<View

android:background=”#efefef”

android:layout_width=”match_parent”

android:layout_height=”1dp” />

 

<LinearLayout

android:padding=”16dp”

android:orientation=”horizontal”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”>

 

<TextView

android:textColor=”#6200ea”

android:text=”ansta_”

android:id=”@+id/tv_username”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

<TextView

android:layout_marginLeft=”8dp”

android:text=”불꽃놀이했어요~~”

android:id=”@+id/tv_posttext”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

</LinearLayout>

 

</LinearLayout>

 

 

 

 

Thread

 

 

 

package com.example.mytestappthread;

 

import android.os.AsyncTask;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.TextView;

 

public class MainActivity extends AppCompatActivity {

 

private TextView tvDisplay;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

tvDisplay = findViewById(R.id.tv_display);

 

findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

startAsyncCalculation();

}

});

}

 

private void startAsyncCalculation() {

AsyncCalculateTask task = new AsyncCalculateTask();

task.execute(1, Integer.MAX_VALUE);

}

 

class AsyncCalculateTask extends AsyncTask<Integer, Integer, Integer> {

 

@Override

protected Integer doInBackground(Integer… integers) {

 

int number = integers[0];

int count = integers[1];

int result = 0;

 

int percentUnit = count / 100;

 

for (int i = 0; i < count; i++) {

result += number;

 

if (result % percentUnit == 0) {

publishProgress(result/percentUnit);

}

}

return result;

}

 

// 전

@Override

protected void onPreExecute() {

super.onPreExecute();

}

 

// 진행상황

@Override

protected void onProgressUpdate(Integer… values) {

super.onProgressUpdate(values);

tvDisplay.setText(values[0] + ” Percent”);

// 로깅

Log.d(“AsyncCalculateTask”, values[0] + ” Percent”);

}

 

// 후

@Override

protected void onPostExecute(Integer integer) {

super.onPostExecute(integer);

tvDisplay.setText(“Result : ” + integer);

}

}

}

 

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout 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”

android:orientation=”vertical”

android:padding=”16dp”

tools:context=”.MainActivity”>

 

<TextView

android:id=”@+id/tv_display”

android:textSize=”24sp”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:text=”Hello World!” />

 

<Button

android:id=”@+id/btn_start”

android:text=”Start”

android:layout_width=”match_parent”

android:layout_height=”wrap_content” />

</LinearLayout>

 

 

 

 

 

 

Glide

 

https://github.com/bumptech/glide

 

https://stackoverflow.com/questions/45481756/glide-4-0-0-missing-placeholder-error-glideapp-and-does-not-resolve-its-method

 

https://d2.naver.com/helloworld/429368

 

https://gun0912.tistory.com/17

 

GlideApp 을 사용하려면

 

If you wanna use GlideApp you have to add to dependencies annotation processor like on the screenshot

 

then include an AppGlideModule implementation in your application:

@GlideModule

public final class MyAppGlideModule extends AppGlideModule {}

 

 

Do not forget about the @GlideModule annotation. Then you need to Build project. And GlideApp will be automatically generated. Hope this is still helpful.

 

dependencies {

implementation ‘com.github.bumptech.glide:glide:4.8.0’

annotationProcessor ‘com.github.bumptech.glide:compiler:4.8.0’

}

 

권한 추가

 

<uses-permission android:name=”android.permission.INTERNET” />

 

String url = “https://”;

Glide.with(this).load(url).into(imageView);

 

 

GlideApp 추가 후 가능

 

GlideApp

.with(this)

.load(url)

.centerCrop()

.placeholder(R.drawable.loading_spinner)

.into(myImageView);

 

package com.example.mytestappglide;

 

 

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.ImageView;

 

public class MainActivity extends AppCompatActivity {

 

ImageView ivHyeWon;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

ivHyeWon = findViewById(R.id.iv_hyewon);

findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

startLoadingHyeWonImage();

}

});

}

 

private void startLoadingHyeWonImage() {

String url = “https://i.pinimg.com/originals/d3/c0/da/d3c0da7cfa12d081630fb3784c1d9789.jpg”;

 

GlideApp.with(this).load(url).centerCrop().placeholder(R.mipmap.ic_launcher).into(ivHyeWon);

}

}

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout 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”

android:orientation=”vertical”

tools:context=”.MainActivity”>

 

<ImageView

android:id=”@+id/iv_hyewon”

android:layout_width=”match_parent”

android:layout_height=”500dp” />

 

<Button

android:id=”@+id/btn_start”

android:text=”시작”

android:layout_width=”match_parent”

android:layout_height=”wrap_content” />

 

</LinearLayout>

 

 

 

 

서버-클라이언트, Okhttp, JSON

 

 

android {

compileOptions {

sourceCompatibility JavaVersion.VERSION_1_8

targetCompatibility JavaVersion.VERSION_1_8

}

}

 

dependencies {

implementation ‘com.android.support:design:28.0.0’  // Tap

implementation ‘com.android.support:recyclerview-v7:28.0.0’

implementation ‘com.github.bumptech.glide:glide:4.8.0’

annotationProcessor ‘com.github.bumptech.glide:compiler:4.8.0’

implementation ‘com.squareup.okhttp3:okhttp:3.13.1’

implementation ‘com.google.code.gson:gson:2.8.5’

}

 

 

 

api/Api.java

 

package com.example.mytestappnetwork.api;

 

public class Api {

public static final String BASE_URL = “http://hooni30.tistory.com”;

public static final String GET_POST = BASE_URL + “/attachment/cfile27.uf@99E5BA4C5C60F727160043.json”;

 

public static  class Post {

int id;

String uploader;

String text;

int likes;

 

public int getId() {

return id;

}

 

public String getUploader() {

return uploader;

}

 

public String getText() {

return text;

}

 

public int getLikes() {

return likes;

}

 

public String getCreated_at() {

return created_at;

}

 

public String getUpdated_at() {

return updated_at;

}

 

public Image getImage() {

return image;

}

 

String created_at;

String updated_at;

Image image;

 

public static class Image {

public String getUrl() {

return url;

}

 

String url;

}

}

}

 

 

 

EmptyFragment.java

 

package com.example.mytestappnetwork;

 

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

public class EmptyFragment extends Fragment {

 

 

public EmptyFragment() {

// Required empty public constructor

}

 

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

return inflater.inflate(R.layout.fragment_empty, container, false);

}

 

}

 

 

 

MainActivity.java

 

package com.example.mytestappnetwork;

 

import android.support.design.widget.TabLayout;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentPagerAdapter;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

 

public class MainActivity extends AppCompatActivity {

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

ViewPager viewPager = findViewById(R.id.vp_pager);

TabLayout tabLayout = findViewById(R.id.tl_tabs);

 

Fragment[] arrFragments = new Fragment[2];

arrFragments[0] = new TimelineFragment();

arrFragments[1] = new EmptyFragment();

 

MainPagerAdapter adapter = new MainPagerAdapter(getSupportFragmentManager(), arrFragments);

 

viewPager.setAdapter(adapter);

tabLayout.setupWithViewPager(viewPager);

 

}

 

class MainPagerAdapter extends FragmentPagerAdapter {

 

Fragment[] arrFragments;

 

public MainPagerAdapter(FragmentManager fm, Fragment[] arrFragments) {

super(fm);

this.arrFragments = arrFragments;

}

 

@Override

public CharSequence getPageTitle(int position) {

 

switch (position) {

case 0:

return “Timeline”;

case 1:

return “Empty”;

default:

return “”;

}

}

 

@Override

public Fragment getItem(int position) {

return arrFragments[position];

}

 

@Override

public int getCount() {

return arrFragments.length;

}

}

}

 

 

 

TimelineFragment.java

 

package com.example.mytestappnetwork;

 

import android.os.AsyncTask;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.support.v7.widget.LinearLayoutManager;

import android.support.v7.widget.RecyclerView;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

import android.widget.TextView;

 

import com.bumptech.glide.Glide;

import com.example.mytestappnetwork.api.Api;

import com.google.gson.Gson;

 

import java.io.IOException;

import java.util.ArrayList;

 

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.Response;

 

public class TimelineFragment extends Fragment {

 

ArrayList<Api.Post> arrayList;

PostViewAdapter postViewAdapter;

 

public TimelineFragment() {

// Required empty public constructor

}

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

 

fetchAsyncPosts();

 

// Inflate the layout for this fragment

View baseView = inflater.inflate(R.layout.fragment_timeline, container, false);

RecyclerView recyclerView = baseView.findViewById(R.id.rv_list);

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));

postViewAdapter = new PostViewAdapter();

recyclerView.setAdapter(postViewAdapter);

 

return baseView;

}

 

private void fetchAsyncPosts() {

arrayList = new ArrayList<>();

FetchPostsTask fetchPostsTask = new FetchPostsTask();

fetchPostsTask.execute(Api.GET_POST);

}

 

class FetchPostsTask extends AsyncTask<String, Void, Api.Post[]> {

 

@Override

protected Api.Post[] doInBackground(String… strings) {

String url = strings[0];

 

OkHttpClient client = new OkHttpClient();

 

Request request = new Request.Builder()

.url(url)

.build();

 

try {

Response response = client.newCall(request).execute();

 

Gson gson = new Gson();

Api.Post[] posts = gson.fromJson(response.body().charStream(), Api.Post[].class);

return posts;

} catch (IOException e) {

Log.d(“FetchPostsTask”, e.getMessage());

return null;

}

}

 

@Override

protected void onPostExecute(Api.Post[] posts) {

super.onPostExecute(posts);

 

for (Api.Post post : posts) {

arrayList.add(post);

}

 

postViewAdapter.notifyDataSetChanged();

}

}

 

class PostViewAdapter extends RecyclerView.Adapter<PostViewHolder> {

 

@Override

public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View baseView = getActivity().getLayoutInflater().inflate(R.layout.item_post, parent, false);

PostViewHolder postViewHolder = new PostViewHolder(baseView);

return postViewHolder;

}

 

@Override

public void onBindViewHolder(PostViewHolder holder, int position) {

 

Api.Post item = arrayList.get(position);

 

String url = item.getImage().getUrl();

 

Glide.with(TimelineFragment.this)

.load(url)

.into(holder.iv_post);

 

holder.tv_username.setText(item.getUploader());

holder.tv_posttext.setText(item.getText());

holder.tv_postlikecount.setText( String.valueOf( item.getLikes() ) );

}

 

@Override

public int getItemCount() {

return arrayList.size();

}

}

 

class PostViewHolder extends RecyclerView.ViewHolder {

 

public TextView tv_username, tv_postlikecount, tv_posttext;

public ImageView iv_post;

 

public PostViewHolder(View itemView) {

super(itemView);

iv_post = itemView.findViewById(R.id.iv_post_img);

tv_username = itemView.findViewById(R.id.tv_user_nickname);

tv_postlikecount = itemView.findViewById(R.id.tv_like_count);

tv_posttext = itemView.findViewById(R.id.tv_post_text);

 

}

}

 

}

 

 

 

activity_main.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<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”

tools:context=”.MainActivity”>

 

<android.support.design.widget.TabLayout

android:id=”@+id/tl_tabs”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”/>

 

<android.support.v4.view.ViewPager

android:layout_below=”@id/tl_tabs”

android:id=”@+id/vp_pager”

android:layout_width=”match_parent”

android:layout_height=”match_parent”/>

 

</RelativeLayout>

 

 

 

fragment_empty.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<FrameLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:background=”#ce93d8″

android:layout_width=”match_parent” android:layout_height=”match_parent”>

 

</FrameLayout>

 

 

 

fragment_timeline.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<FrameLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:layout_width=”match_parent” android:layout_height=”match_parent”>

 

<android.support.v7.widget.RecyclerView

android:id=”@+id/rv_list”

android:layout_width=”match_parent”

android:layout_height=”match_parent”/>

 

</FrameLayout>

 

 

 

item_post.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:orientation=”vertical” android:layout_width=”match_parent”

android:layout_height=”wrap_content”>

 

<ImageView

android:scaleType=”centerCrop”

android:id=”@+id/iv_post_img”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:background=”#ffee58″

android:minHeight=”400dp” />

 

<RelativeLayout

android:layout_width=”match_parent”

android:layout_height=”37dp”

android:paddingLeft=”16dp”

android:paddingRight=”16dp”>

 

<View

android:id=”@+id/chk_like”

android:layout_width=”24dp”

android:layout_height=”24dp”

android:layout_centerVertical=”true”

android:background=”#d50000″ />

 

<TextView

android:id=”@+id/tv_like_count”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_centerVertical=”true”

android:layout_marginLeft=”8dp”

android:layout_toRightOf=”@id/chk_like”

android:text=”1234″ />

 

<View

android:id=”@+id/v_share”

android:layout_width=”24dp”

android:layout_height=”24dp”

android:layout_alignParentRight=”true”

android:layout_centerVertical=”true”

android:background=”#000000″ />

 

</RelativeLayout>

 

<View android:layout_width=”match_parent”

android:layout_height=”1dp”

android:background=”#e3e3e3″ />

 

<LinearLayout

android:layout_width=”match_parent”

android:layout_height=”37dp”

android:gravity=”center_vertical”

android:orientation=”horizontal”

android:paddingLeft=”16dp”

android:paddingRight=”16dp”>

 

<TextView

android:id=”@+id/tv_user_nickname”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:text=”ansta_”

android:textColor=”#28417a” />

 

<TextView

android:id=”@+id/tv_post_text”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_marginLeft=”4dp”

android:text=”불꽃놀이했어요~” />

 

</LinearLayout>

 

</LinearLayout>

 

 

 

 

 

 

카메라

 

    <uses-permission android:name=”android.permission.INTERNET” />

<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE” />

 

android {

compileOptions {

sourceCompatibility JavaVersion.VERSION_1_8

targetCompatibility JavaVersion.VERSION_1_8

}

}

 

dependencies {

implementation fileTree(include: [‘*.jar’], dir: ‘libs’)

implementation ‘com.android.support:appcompat-v7:28.0.0’

implementation ‘com.android.support.constraint:constraint-layout:1.1.3’

testImplementation ‘junit:junit:4.12’

androidTestImplementation ‘com.android.support.test:runner:1.0.2’

androidTestImplementation ‘com.android.support.test.espresso:espresso-core:3.0.2’

implementation ‘com.android.support:design:28.0.0’

implementation ‘com.android.support:recyclerview-v7:28.0.0’

implementation ‘com.squareup.okhttp3:okhttp:3.13.1’

implementation ‘com.google.code.gson:gson:2.8.5’

implementation ‘com.github.bumptech.glide:glide:4.8.0’

}

 

api/Api.java

 

package com.example.mytestappcamera.api;

 

/**

* Created by g82 on 5/6/16.

*/

public class Api {

 

public static final String BASE_URL = “http://hooni30.tistory.com”;

public static final String GET_POST = BASE_URL + “/attachment/cfile27.uf@99E5BA4C5C60F727160043.json”;

 

public static class Image {

String url;

 

public String getUrl() {

return url;

}

}

 

/**

* {

* “id”: 1,

* “uploader”: “g82”,

* “text”: “현영아…”,

* “likes”: 0,

* “created_at”: “2016-05-05T07:27:35.962Z”,

* “updated_at”: “2016-05-05T07:27:35.962Z”,

* “image”: {

* “url”: “/uploads/post/image/1/IMG_6940.jpg”

* }

* }

*/

 

public static class Post {

 

int id;

String uploader;

String text;

int likes;

String created_at;

String updated_at;

Image image;

 

public int getId() {

return id;

}

 

public String getUploader() {

return uploader;

}

 

public String getText() {

return text;

}

 

public int getLikes() {

return likes;

}

 

public String getCreated_at() {

return created_at;

}

 

public String getUpdated_at() {

return updated_at;

}

 

public Image getImage() {

return image;

}

 

 

}

 

}

 

 

 

EmptyFragment.java

 

package com.example.mytestappcamera;

 

 

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

 

/**

* A simple {@link Fragment} subclass.

*/

public class EmptyFragment extends Fragment {

 

 

public EmptyFragment() {

// Required empty public constructor

}

 

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

return inflater.inflate(R.layout.fragment_empty, container, false);

}

 

}

 

 

 

MainActivity.java

 

package com.example.mytestappcamera;

 

import android.content.pm.PackageManager;

import android.os.Bundle;

import android.support.annotation.NonNull;

import android.support.design.widget.TabLayout;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentPagerAdapter;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

 

public class MainActivity extends AppCompatActivity {

 

/**

* TODO

* MainActivity

*  ViewPager (below), TabLayout (above)

*

*  2 Fragment

*  TimelineFragment, EmptyFragment

*/

 

Fragment[] arrFragments;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

ViewPager viewPager = findViewById(R.id.vp_pager);

TabLayout tabLayout = findViewById(R.id.tl_tabs);

 

arrFragments = new Fragment[2];

arrFragments[0] = new TimelineFragment();

arrFragments[1] = new EmptyFragment();

 

MainPagerAdapter adapter = new MainPagerAdapter(getSupportFragmentManager(), arrFragments);

 

viewPager.setAdapter(adapter);

tabLayout.setupWithViewPager(viewPager);

}

 

@Override

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

super.onRequestPermissionsResult(requestCode, permissions, grantResults);

 

if (requestCode == 2000 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

TimelineFragment timelineFragment = (TimelineFragment) arrFragments[0];

timelineFragment.startCameraActivity();

}

}

 

class MainPagerAdapter extends FragmentPagerAdapter {

 

Fragment[] arrFragments;

 

public MainPagerAdapter(FragmentManager fm, Fragment[] arrFragments) {

super(fm);

this.arrFragments = arrFragments;

}

 

@Override

public CharSequence getPageTitle(int position) {

 

switch (position) {

case 0:

return “Timeline”;

case 1:

return “Empty”;

default:

return “”;

}

}

 

@Override

public Fragment getItem(int position) {

return arrFragments[position];

}

 

@Override

public int getCount() {

return arrFragments.length;

}

}

 

}

 

 

 

PostActivity.java

 

package com.example.mytestappcamera;

 

import android.content.Intent;

import android.graphics.Bitmap;

import android.net.Uri;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.widget.ImageView;

 

public class PostActivity extends AppCompatActivity {

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_post);

 

ImageView ivPost = findViewById(R.id.iv_post);

 

Intent intent = getIntent();

Bitmap bitmap = intent.getParcelableExtra(“BitmapImage”);

ivPost.setImageBitmap(bitmap);

 

// Uri photoUri = intent.getData();

// ivPost.setImageURI(photoUri);

}

}

 

 

 

TimelineFragment.java

 

package com.example.mytestappcamera;

 

 

import android.Manifest;

import android.app.Activity;

import android.content.Intent;

import android.content.pm.PackageManager;

import android.graphics.Bitmap;

import android.os.AsyncTask;

import android.os.Bundle;

import android.provider.MediaStore;

import android.support.annotation.NonNull;

import android.support.v4.app.ActivityCompat;

import android.support.v4.app.Fragment;

import android.support.v4.content.ContextCompat;

import android.support.v7.widget.LinearLayoutManager;

import android.support.v7.widget.RecyclerView;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

import android.widget.TextView;

 

import com.bumptech.glide.Glide;

import com.example.mytestappcamera.api.Api;

import com.google.gson.Gson;

 

import java.io.IOException;

import java.util.ArrayList;

 

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.Response;

 

 

/**

* 8-C

* https://goo.gl/91iKsb

*

*/

public class TimelineFragment extends Fragment {

 

ArrayList<Api.Post> arrayList;

PostViewAdapter postViewAdapter;

 

public TimelineFragment() {

// Required empty public constructor

}

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

 

fetchAsyncPosts();

 

// Inflate the layout for this fragment

View baseView = inflater.inflate(R.layout.fragment_timeline, container, false);

RecyclerView recyclerView = baseView.findViewById(R.id.rv_list);

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));

postViewAdapter = new PostViewAdapter();

recyclerView.setAdapter(postViewAdapter);

 

baseView.findViewById(R.id.fab_post).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

int permissionCheck = ContextCompat.checkSelfPermission(getActivity(),

Manifest.permission.READ_EXTERNAL_STORAGE);

 

if (permissionCheck == PackageManager.PERMISSION_GRANTED) {

startCameraActivity();

}

else {

ActivityCompat.requestPermissions(getActivity(),

new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},

2000);

//Toast.makeText(getActivity(), “권한이 업습니다.”, Toast.LENGTH_SHORT).show();

}

}

});

 

return baseView;

}

 

public void startCameraActivity() {

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {

startActivityForResult(cameraIntent, 1000);

}

}

 

@Override

public void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

 

if (requestCode == 1000 && resultCode == Activity.RESULT_OK) {

Log.d(“onActivityResult”, “Camera SUCCESS”);

Bitmap bitmap = (Bitmap)data.getExtras().get(“data”);

Intent startIntent = new Intent(getActivity(), PostActivity.class);

startIntent.putExtra(“BitmapImage”, bitmap);

// startIntent.setData(data.getData());   결과가 Uri 일 때.

startActivity(startIntent);

}

}

 

private void fetchAsyncPosts() {

arrayList = new ArrayList<>();

FetchPostsTask fetchPostsTask = new FetchPostsTask();

fetchPostsTask.execute(Api.GET_POST);

}

 

class FetchPostsTask extends AsyncTask<String, Void, Api.Post[]> {

 

@Override

protected Api.Post[] doInBackground(String… strings) {

 

String url = strings[0];

 

OkHttpClient client = new OkHttpClient();

 

Request request = new Request.Builder()

.url(url)

.build();

 

try {

Response response = client.newCall(request).execute();

 

Gson gson = new Gson();

Api.Post[] posts = gson.fromJson(response.body().charStream(), Api.Post[].class);

 

return posts;

 

} catch (IOException e) {

Log.d(“FetchPostsTask”, e.getMessage());

return null;

}

}

 

@Override

protected void onPostExecute(Api.Post[] posts) {

super.onPostExecute(posts);

for (Api.Post post : posts) {

arrayList.add(post);

}

postViewAdapter.notifyDataSetChanged();

}

}

 

class PostViewAdapter extends RecyclerView.Adapter<PostViewHolder> {

 

@Override

public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View baseView = getActivity().getLayoutInflater().inflate(R.layout.item_post, parent, false);

PostViewHolder postViewHolder = new PostViewHolder(baseView);

return postViewHolder;

}

 

@Override

public void onBindViewHolder(PostViewHolder holder, int position) {

 

Api.Post item = arrayList.get(position);

 

String url = item.getImage().getUrl();

 

Glide.with(TimelineFragment.this)

.load(url)

.into(holder.iv_post);

 

holder.tv_username.setText(item.getUploader());

holder.tv_posttext.setText(item.getText());

holder.tv_postlikecount.setText(String.valueOf(item.getLikes()));

}

 

@Override

public int getItemCount() {

return arrayList.size();

}

}

 

class PostViewHolder extends RecyclerView.ViewHolder {

 

public TextView tv_username, tv_postlikecount, tv_posttext;

public ImageView iv_post;

 

public PostViewHolder(View itemView) {

super(itemView);

iv_post = itemView.findViewById(R.id.iv_post_img);

tv_username = itemView.findViewById(R.id.tv_user_nickname);

tv_postlikecount = itemView.findViewById(R.id.tv_like_count);

tv_posttext = itemView.findViewById(R.id.tv_post_text);

 

}

}

 

}

 

 

 

activity_main.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<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”

tools:context=”.MainActivity”>

 

<android.support.design.widget.TabLayout

android:id=”@+id/tl_tabs”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”/>

 

<android.support.v4.view.ViewPager

android:layout_below=”@id/tl_tabs”

android:id=”@+id/vp_pager”

android:layout_width=”match_parent”

android:layout_height=”match_parent”/>

 

</RelativeLayout>

 

 

 

activity_post.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<android.support.constraint.ConstraintLayout 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”

tools:context=”.PostActivity”>

 

<ImageView

android:id=”@+id/iv_post”

android:layout_width=”match_parent”

android:layout_height=”300dp” />

 

</android.support.constraint.ConstraintLayout>

 

 

 

fragment_empty.xml

 

<FrameLayout 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:background=”#ce93d8″

tools:context=”.EmptyFragment”>

 

</FrameLayout>

 

 

 

fragment_timeline.xml

 

<FrameLayout 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”

tools:context=”.TimelineFragment”>

 

<android.support.v7.widget.RecyclerView

android:id=”@+id/rv_list”

android:layout_width=”match_parent”

android:layout_height=”match_parent”/>

 

<android.support.design.widget.FloatingActionButton

android:layout_marginRight=”16dp”

android:layout_marginBottom=”16dp”

android:layout_gravity=”bottom|right”

android:id=”@+id/fab_post”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

</FrameLayout>

 

 

 

item_friend.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:padding=”16dp”

android:layout_width=”match_parent” android:layout_height=”wrap_content”>

 

<ImageView

android:id=”@+id/iv_img”

android:background=”#ffb115″

android:layout_width=”48dp”

android:layout_height=”48dp” />

 

<TextView

android:id=”@+id/tv_name”

android:textSize=”18sp”

android:layout_marginLeft=”8dp”

android:layout_centerVertical=”true”

android:layout_toRightOf=”@id/iv_img”

android:layout_toLeftOf=”@+id/tv_status”

android:layout_marginRight=”8dp”

android:lines=”1″

android:text=”겜팔이 이름”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

<TextView

android:id=”@+id/tv_status”

android:padding=”8dp”

android:background=”#ffb115″

android:layout_centerVertical=”true”

android:layout_alignParentRight=”true”

android:maxLines=”2″

android:maxWidth=”100dp”

android:text=”카톡안함”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

 

</RelativeLayout>

 

 

 

item_post.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:orientation=”vertical”>

 

<ImageView

android:id=”@+id/iv_post_img”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:background=”#ffee58″

android:minHeight=”400dp” />

 

<RelativeLayout

android:layout_width=”match_parent”

android:layout_height=”37dp”

android:paddingLeft=”16dp”

android:paddingRight=”16dp”>

 

<View

android:id=”@+id/chk_like”

android:layout_width=”24dp”

android:layout_height=”24dp”

android:layout_centerVertical=”true”

android:background=”#d50000″ />

 

<TextView

android:id=”@+id/tv_like_count”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_centerVertical=”true”

android:layout_marginLeft=”8dp”

android:layout_toRightOf=”@id/chk_like”

android:text=”1234″ />

 

<View

android:id=”@+id/v_share”

android:layout_width=”24dp”

android:layout_height=”24dp”

android:layout_alignParentRight=”true”

android:layout_centerVertical=”true”

android:background=”#000000″ />

 

</RelativeLayout>

 

<View android:layout_width=”match_parent”

android:layout_height=”1dp”

android:background=”#e3e3e3″ />

 

<LinearLayout

android:layout_width=”match_parent”

android:layout_height=”37dp”

android:gravity=”center_vertical”

android:orientation=”horizontal”

android:paddingLeft=”16dp”

android:paddingRight=”16dp”>

 

<TextView

android:id=”@+id/tv_user_nickname”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:text=”ansta_”

android:textColor=”#28417a” />

 

<TextView

android:id=”@+id/tv_post_text”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_marginLeft=”4dp”

android:text=”불꽃놀이했어요~” />

 

</LinearLayout>

 

</LinearLayout>

 

 

 

 

 

13. 최종 10강 완결 소스

 

 

app/build.gradle

 

apply plugin: ‘com.android.application’

 

android {

compileSdkVersion 23

buildToolsVersion “23.0.3”

 

defaultConfig {

applicationId “madwhale.g82.com.anstagram_gangnam”

minSdkVersion 16

targetSdkVersion 23

versionCode 1

versionName “1.0”

}

buildTypes {

release {

minifyEnabled false

proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’

}

}

}

 

dependencies {

compile fileTree(dir: ‘libs’, include: [‘*.jar’])

testCompile ‘junit:junit:4.12’

compile ‘com.github.bumptech.glide:glide:3.7.0’

compile ‘com.squareup.okhttp3:okhttp:3.2.0’

compile ‘com.google.code.gson:gson:2.6.2’

compile ‘com.android.support:appcompat-v7:23.3.0’

compile ‘com.android.support:design:23.3.0’

compile ‘com.android.support:recyclerview-v7:23.3.0’

compile ‘com.android.support:support-v4:23.3.0’

}

 

 

 

 

AndroidManifest.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<manifest xmlns:android=”http://schemas.android.com/apk/res/android”

package=”madwhale.g82.com.anstagram_gangnam”>

 

<uses-permission android:name=”android.permission.INTERNET” />

<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE” />

 

<application

android:allowBackup=”true”

android:icon=”@mipmap/ic_launcher”

android:label=”@string/app_name”

android:supportsRtl=”true”

android:theme=”@style/AppTheme”>

<activity android:name=”.MainActivity”>

<intent-filter>

<action android:name=”android.intent.action.MAIN” />

 

<category android:name=”android.intent.category.LAUNCHER” />

</intent-filter>

</activity>

<activity android:name=”.PostActivity”></activity>

</application>

 

</manifest>

 

 

 

 

EmptyFragment.java

 

package madwhale.g82.com.anstagram_gangnam;

 

 

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

 

 

/**

* A simple {@link Fragment} subclass.

*/

public class EmptyFragment extends Fragment {

 

 

public EmptyFragment() {

// Required empty public constructor

}

 

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

return inflater.inflate(R.layout.fragment_empty, container, false);

}

}

 

 

 

 

MainActivity.java

 

package madwhale.g82.com.anstagram_gangnam;

 

import android.os.Bundle;

import android.support.annotation.NonNull;

import android.support.design.widget.TabLayout;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentPagerAdapter;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

 

public class MainActivity extends AppCompatActivity {

 

/**

* TODO

* MainActivity

*  ViewPager (below), TabLayout (above)

*

*  2 Fragment

*  TimelineFragment, EmptyFragment

*/

 

Fragment[] arrFragments;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

ViewPager viewPager = (ViewPager) findViewById(R.id.vp_pager);

TabLayout tabLayout = (TabLayout) findViewById(R.id.tl_tabs);

 

arrFragments = new Fragment[2];

arrFragments[0] = new TimelineFragment();

arrFragments[1] = new EmptyFragment();

 

MainPagerAdapter adapter = new MainPagerAdapter(getSupportFragmentManager(), arrFragments);

 

viewPager.setAdapter(adapter);

tabLayout.setupWithViewPager(viewPager);

}

 

@Override

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

super.onRequestPermissionsResult(requestCode, permissions, grantResults);

 

if (requestCode == 2000 && grantResults.length > 0) {

TimelineFragment timelineFragment = (TimelineFragment) arrFragments[0];

timelineFragment.startCameraActivity();

}

}

 

class MainPagerAdapter extends FragmentPagerAdapter {

 

Fragment[] arrFragments;

 

public MainPagerAdapter(FragmentManager fm, Fragment[] arrFragments) {

super(fm);

this.arrFragments = arrFragments;

}

 

@Override

public CharSequence getPageTitle(int position) {

 

switch (position) {

case 0:

return “Timeline”;

case 1:

return “Empty”;

default:

return “”;

}

}

 

@Override

public Fragment getItem(int position) {

return arrFragments[position];

}

 

@Override

public int getCount() {

return arrFragments.length;

}

}

 

}

 

 

 

 

PostActivity.java

 

package madwhale.g82.com.anstagram_gangnam;

 

import android.app.ProgressDialog;

import android.content.Intent;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.ParcelFileDescriptor;

import android.support.v7.app.AppCompatActivity;

import android.util.Log;

import android.view.View;

import android.widget.EditText;

import android.widget.ImageView;

import android.widget.Toast;

 

import com.bumptech.glide.Glide;

 

import java.io.File;

import java.io.FileDescriptor;

import java.io.FileOutputStream;

import java.io.IOException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.concurrent.TimeUnit;

 

import madwhale.g82.com.anstagram_gangnam.api.Api;

import madwhale.g82.com.anstagram_gangnam.uuid.UserUUID;

import okhttp3.MediaType;

import okhttp3.MultipartBody;

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.RequestBody;

import okhttp3.Response;

 

public class PostActivity extends AppCompatActivity {

 

EditText etText;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_post);

 

Intent intent = getIntent();

final Uri photoUri = intent.getData();

 

ImageView ivPost = (ImageView) findViewById(R.id.iv_post);

etText = (EditText) findViewById(R.id.et_text);

findViewById(R.id.btn_post).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

post(photoUri.toString(), etText.getText().toString());

}

});

 

Glide.with(this)

.load(photoUri)

.centerCrop()

.crossFade()

.into(ivPost);

 

/** Uri content://media/external/images/media/255 */

// Uri -> Bitmap -> File

}

 

private void post(String uriString, String textString) {

PostTask postTask = new PostTask();

postTask.execute(uriString, textString);

}

 

private Bitmap getBitmapFromUri(Uri uri) throws IOException {

ParcelFileDescriptor parcelFileDescriptor =

getContentResolver().openFileDescriptor(uri, “r”);

FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();

 

BitmapFactory.Options opts = new BitmapFactory.Options();

opts.inJustDecodeBounds = true;

BitmapFactory.decodeFileDescriptor(fileDescriptor, null, opts);

 

int width = opts.outWidth;

int height = opts.outHeight;

 

float sampleRatio = getSampleRatio(width, height);

 

opts.inJustDecodeBounds = false;

opts.inSampleSize = (int) sampleRatio;

 

Bitmap resizedBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, opts);

 

Log.d(“Resizing”, “Resized Width / Height : ” + resizedBitmap.getWidth() + “/” + resizedBitmap.getHeight());

 

parcelFileDescriptor.close();

 

return resizedBitmap;

}

 

// 5312 x 2988

private float getSampleRatio(int width, int height) {

 

final int targetWidth = 1280;

final int targetheight = 1280;

 

float ratio;

 

if (width > height) {

// Landscape

if (width > targetWidth) {

ratio = (float) width / (float) targetWidth;

} else ratio = 1f;

} else {

// Portrait

if (height > targetheight) {

ratio = (float) height / (float) targetheight;

} else ratio = 1f;

}

 

return Math.round(ratio);

}

 

 

private File createFileFromBitmap(Bitmap bitmap) throws IOException {

 

File newFile = new File(getFilesDir(), makeImageFileName());

 

FileOutputStream fileOutputStream = new FileOutputStream(newFile);

bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);

fileOutputStream.close();

 

return newFile;

}

 

private String makeImageFileName() {

 

SimpleDateFormat simpleDateFormat = new SimpleDateFormat(“yyyyMMdd_hhmmss”);

Date date = new Date();

String strDate = simpleDateFormat.format(date);

return strDate + “.png”;

}

 

class PostTask extends AsyncTask<String, Void, Boolean> {

 

ProgressDialog progressDialog;

 

@Override

protected void onPreExecute() {

super.onPreExecute();

progressDialog = ProgressDialog.show(PostActivity.this, “포스트 업로드 중”, “잠시만 기다려주세요..”, true, false);

}

 

@Override

protected Boolean doInBackground(String… strings) {

 

/** Ready for post */

Uri imageUri = Uri.parse(strings[0]);

String text = strings[1];

 

try {

Bitmap bitmap = getBitmapFromUri(imageUri);

File imageFile = createFileFromBitmap(bitmap);

 

 

/** HTTP POST */

RequestBody requestBody = new MultipartBody.Builder()

.setType(MultipartBody.FORM)

.addFormDataPart(“uploader”, UserUUID.getUserUUID(PostActivity.this))

.addFormDataPart(“text”, text)

.addFormDataPart(“image”, makeImageFileName(),

RequestBody.create(MediaType.parse(“image/png”), imageFile))

.build();

 

Request request = new Request.Builder()

.url(Api.UP_POST)

.post(requestBody)

.build();

 

OkHttpClient okHttpClient = new OkHttpClient.Builder()

.connectTimeout(20, TimeUnit.SECONDS)

.readTimeout(20, TimeUnit.SECONDS)

.writeTimeout(20, TimeUnit.SECONDS)

.build();

 

Response response = okHttpClient.newCall(request).execute();

 

return response.code() == 200;

 

} catch (IOException e) {

Log.d(“PostTask”, “post failed”, e);

return false;

}

}

 

@Override

protected void onPostExecute(Boolean aBoolean) {

super.onPostExecute(aBoolean);

progressDialog.dismiss();

if (aBoolean) {

Toast.makeText(PostActivity.this, “success”, Toast.LENGTH_SHORT).show();

Log.d(“PostTask”, “success”);

} else Log.d(“PostTask”, “failed”);

}

}

}

 

 

 

TimelineFragment.java

 

package madwhale.g82.com.anstagram_gangnam;

 

 

import android.Manifest;

import android.app.Activity;

import android.content.Intent;

import android.content.pm.PackageManager;

import android.os.AsyncTask;

import android.os.Bundle;

import android.provider.MediaStore;

import android.support.v4.app.ActivityCompat;

import android.support.v4.app.Fragment;

import android.support.v4.content.ContextCompat;

import android.support.v7.widget.LinearLayoutManager;

import android.support.v7.widget.RecyclerView;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.CheckBox;

import android.widget.ImageView;

import android.widget.TextView;

 

import com.bumptech.glide.Glide;

import com.google.gson.Gson;

import com.google.gson.JsonSyntaxException;

 

import java.io.IOException;

import java.util.ArrayList;

 

import madwhale.g82.com.anstagram_gangnam.api.Api;

import madwhale.g82.com.anstagram_gangnam.uuid.UserUUID;

import okhttp3.FormBody;

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.RequestBody;

import okhttp3.Response;

 

 

/**

* 10-E

*/

public class TimelineFragment extends Fragment {

 

 

ArrayList<Api.Post> arrayList;

PostViewAdapter postViewAdapter;

 

private String user_id;

 

public TimelineFragment() {

// Required empty public constructor

}

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

 

user_id = UserUUID.getUserUUID(getActivity());

 

fetchAsyncPosts();

 

// Inflate the layout for this fragment

View baseView = inflater.inflate(R.layout.fragment_timeline, container, false);

RecyclerView recyclerView = (RecyclerView) baseView.findViewById(R.id.rv_list);

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));

postViewAdapter = new PostViewAdapter();

recyclerView.setAdapter(postViewAdapter);

 

baseView.findViewById(R.id.fab_post).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

 

int permissionCheck = ContextCompat.checkSelfPermission(getActivity(),

Manifest.permission.READ_EXTERNAL_STORAGE);

 

if (permissionCheck == PackageManager.PERMISSION_GRANTED) {

//startCameraActivity();

startGallery();

} else {

ActivityCompat.requestPermissions(getActivity(),

new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},

2000);

}

 

 

}

});

return baseView;

}

 

public void startCameraActivity() {

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {

startActivityForResult(cameraIntent, 1000);

}

}

 

public void startGallery() {

Intent cameraIntent = new Intent(Intent.ACTION_GET_CONTENT);

cameraIntent.setType(“image/*”);

if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {

startActivityForResult(cameraIntent, 1000);

}

}

 

/**

* Main(TimelineFrag) -> run Camera -> main -> Post

*/

 

@Override

public void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

 

if (requestCode == 1000 && resultCode == Activity.RESULT_OK) {

Log.d(“onActivityResult”, “Camera SUCCESS”);

Intent startIntent = new Intent(getActivity(), PostActivity.class);

startIntent.setData(data.getData());

startActivity(startIntent);

}

 

}

 

private void fetchAsyncPosts() {

arrayList = new ArrayList<>();

FetchPostsTask fetchPostsTask = new FetchPostsTask();

fetchPostsTask.execute(Api.GET_POST + user_id);

}

 

 

interface OnLikeListener {

void onLike(LikeTaskResponse response);

}

 

class FetchPostsTask extends AsyncTask<String, Void, Api.Post[]> {

 

@Override

protected Api.Post[] doInBackground(String… strings) {

 

String url = strings[0];

 

OkHttpClient client = new OkHttpClient();

 

Request request = new Request.Builder()

.url(url)

.build();

 

try {

Response response = client.newCall(request).execute();

 

Gson gson = new Gson();

Api.Post[] posts = gson.fromJson(response.body().charStream(), Api.Post[].class);

 

return posts;

 

} catch (IOException e) {

Log.d(“FetchPostsTask”, e.getMessage());

return null;

} catch (JsonSyntaxException e) {

Log.d(“FetchPostsTask”, e.getMessage());

return null;

}

}

 

@Override

protected void onPostExecute(Api.Post[] posts) {

super.onPostExecute(posts);

 

if (posts == null) return;

 

for (Api.Post post : posts) {

arrayList.add(post);

}

postViewAdapter.notifyDataSetChanged();

}

}

 

class PostViewAdapter extends RecyclerView.Adapter<PostViewHolder> {

 

@Override

public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

View baseView = getActivity().getLayoutInflater().inflate(R.layout.item_post, parent, false);

PostViewHolder postViewHolder = new PostViewHolder(baseView);

return postViewHolder;

}

 

@Override

public void onBindViewHolder(PostViewHolder holder, int position) {

 

Api.Post item = arrayList.get(position);

 

String url = item.getImage().getUrl();

 

Glide.with(TimelineFragment.this)

.load(url)

.centerCrop()

.crossFade()

.into(holder.iv_post);

 

holder.tv_username.setText(item.getUploader());

holder.tv_posttext.setText(item.getText());

holder.tv_postlikecount.setText(String.valueOf(item.getLikes().getCount()));

holder.chk_like.setChecked(item.getLikes().isUserliked());

}

 

@Override

public int getItemCount() {

return arrayList.size();

}

}

 

class PostViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

 

public TextView tv_username, tv_postlikecount, tv_posttext;

public ImageView iv_post;

public CheckBox chk_like;

 

public PostViewHolder(View itemView) {

super(itemView);

iv_post = (ImageView) itemView.findViewById(R.id.iv_post_img);

tv_username = (TextView) itemView.findViewById(R.id.tv_user_nickname);

tv_postlikecount = (TextView) itemView.findViewById(R.id.tv_like_count);

tv_posttext = (TextView) itemView.findViewById(R.id.tv_post_text);

chk_like = (CheckBox) itemView.findViewById(R.id.chk_like);

chk_like.setOnClickListener(this);

}

 

@Override

public void onClick(View view) {

final int position = getLayoutPosition();

 

Api.Post post = arrayList.get(position);

 

Log.d(“Like”, post.getLikes().isUserliked() + “/” + post.getId() + “/” + user_id);

 

boolean like = !(post.getLikes().isUserliked());

 

LikeTaskRequest likeTaskRequest = new LikeTaskRequest(like, post.getId(), user_id);

LikeTask likeTask = new LikeTask(new OnLikeListener() {

@Override

public void onLike(LikeTaskResponse response) {

Api.Post post = arrayList.get(position);

post.getLikes().setCount(response.getLikes());

post.getLikes().setUserliked(response.isResult());

postViewAdapter.notifyDataSetChanged();

}

});

likeTask.execute(likeTaskRequest);

}

}

 

class LikeTaskRequest {

 

boolean like;

int post_id;

String user_id;

 

public LikeTaskRequest(boolean like, int post_id, String user_id) {

this.like = like;

this.post_id = post_id;

this.user_id = user_id;

}

 

public boolean isLike() {

return like;

}

 

public int getPost_id() {

return post_id;

}

 

public String getUser_id() {

return user_id;

}

}

 

class LikeTaskResponse {

boolean result;

int likes;

 

public boolean isResult() {

return result;

}

 

public int getLikes() {

return likes;

}

}

 

class LikeTask extends AsyncTask<LikeTaskRequest, Void, LikeTaskResponse> {

 

private OnLikeListener onLikeListener;

 

public LikeTask(OnLikeListener onLikeListener) {

this.onLikeListener = onLikeListener;

}

 

@Override

protected LikeTaskResponse doInBackground(LikeTaskRequest… likeTaskRequests) {

 

LikeTaskRequest likeInfo = likeTaskRequests[0];

 

RequestBody requestBody = new FormBody.Builder()

.add(“post_id”, String.valueOf(likeInfo.getPost_id()))

.add(“user_id”, likeInfo.getUser_id())

.build();

 

Request request;

 

if (likeInfo.isLike()) {

request = new Request.Builder()

.url(Api.POST_LIKE)

.post(requestBody)

.build();

} else {

request = new Request.Builder()

.url(Api.DEL_LIKE)

.delete(requestBody)

.build();

}

 

OkHttpClient okHttpClient = new OkHttpClient();

 

try {

Response response = okHttpClient.newCall(request).execute();

 

if (response.code() == 200) {

Gson gson = new Gson();

LikeTaskResponse taskResponse = gson.fromJson(response.body().charStream(), LikeTaskResponse.class);

return taskResponse;

} else {

return null;

}

 

} catch (IOException e) {

Log.d(“LikeTask”, “Error”, e);

return null;

}

}

 

@Override

protected void onPostExecute(LikeTaskResponse likeTaskResponse) {

super.onPostExecute(likeTaskResponse);

onLikeListener.onLike(likeTaskResponse);

Log.d(“Like Response”, likeTaskResponse.getLikes() + “/” + likeTaskResponse.isResult());

}

}

 

}

 

 

 

 

api/Api.java

 

package madwhale.g82.com.anstagram_gangnam.api;

 

/**

* Created by g82 on 5/6/16.

*/

public class Api {

 

public static final String BASE_URL = “http://52.79.195.156:3000”;

public static final String GET_POST = BASE_URL + “/api/post?user_id=”;

public static final String UP_POST = BASE_URL + “/api/post”;

public static final String POST_LIKE = BASE_URL + “/api/post/like”;

public static final String DEL_LIKE = BASE_URL + “/api/post/like”;

 

public static class Image {

String url;

 

public String getUrl() {

return url;

}

}

 

public static class Likes {

int count;

boolean userliked;

 

public int getCount() {

return count;

}

 

public void setCount(int count) {

this.count = count;

}

 

public boolean isUserliked() {

return userliked;

}

 

public void setUserliked(boolean userliked) {

this.userliked = userliked;

}

}

 

/**

*

* {

“id”: 48,

“uploader”: “g82”,

“text”: “하이하이”,

“likes”: {

“count”: 0,

“userliked”: false

},

“image”: {

“url”: “https://bucket-anstagram.s3.ap-northeast-2.amazonaws.com/uploads/post/image/48/20160514_071342.png”

},

“created_at”: “2016-05-14T10:13:46.997Z”,

“updated_at”: “2016-05-14T10:13:46.997Z”

}

*/

 

public static class Post {

 

int id;

String uploader;

String text;

Likes likes;

String created_at;

String updated_at;

Image image;

 

public int getId() {

return id;

}

 

public String getUploader() {

return uploader;

}

 

public String getText() {

return text;

}

 

public Likes getLikes() {

return likes;

}

 

public String getCreated_at() {

return created_at;

}

 

public String getUpdated_at() {

return updated_at;

}

 

public Image getImage() {

return image;

}

 

 

}

 

}

 

 

 

uuid/UserUUID.java

 

package madwhale.g82.com.anstagram_gangnam.uuid;

 

import android.app.Activity;

import android.content.Context;

import android.content.SharedPreferences;

import android.support.annotation.Nullable;

 

import java.util.UUID;

 

/**

* Created by g82 on 5/14/16.

*/

public class UserUUID {

 

private static final String PREF_UUID = “PREF_UUID”;

private static final String PREF_UUID_KEY = “PREF_UUID_KEY”;

 

@Nullable

public static String getUserUUID(Activity activity) {

SharedPreferences sharedPreferences = activity.getSharedPreferences(PREF_UUID, Context.MODE_PRIVATE);

String user_id = sharedPreferences.getString(PREF_UUID_KEY, null);

 

if (user_id == null) {

String uuidStr = UUID.randomUUID().toString();

user_id = uuidStr.substring(0, 8);

 

SharedPreferences.Editor editor = sharedPreferences.edit();

editor.putString(PREF_UUID_KEY, user_id);

editor.commit();

}

 

//f5ad365e

return user_id;

}

 

}

 

 

 

 

activity_main.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<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”

tools:context=”madwhale.g82.com.anstagram_gangnam.MainActivity”>

 

<android.support.design.widget.TabLayout

android:id=”@+id/tl_tabs”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”/>

 

<android.support.v4.view.ViewPager

android:layout_below=”@id/tl_tabs”

android:id=”@+id/vp_pager”

android:layout_width=”match_parent”

android:layout_height=”match_parent”/>

 

</RelativeLayout>

 

 

 

 

activity_post.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<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”

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=”madwhale.g82.com.anstagram_gangnam.PostActivity”>

 

<ImageView

android:id=”@+id/iv_post”

android:layout_width=”match_parent”

android:layout_height=”300dp” />

 

<EditText

android:id=”@+id/et_text”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:hint=”Input your text.”

android:maxLength=”144″

android:maxLines=”2″ />

 

<Button

android:id=”@+id/btn_post”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:text=”Post” />

 

</LinearLayout>

 

 

 

fragment_empty.xml

 

<FrameLayout 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:background=”#ce93d8″

tools:context=”madwhale.g82.com.anstagram_gangnam.EmptyFragment”>

 

</FrameLayout>

 

 

 

 

fragment_timeline.xml

 

<FrameLayout 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”

tools:context=”madwhale.g82.com.anstagram_gangnam.TimelineFragment”>

 

<android.support.v7.widget.RecyclerView

android:id=”@+id/rv_list”

android:layout_width=”match_parent”

android:layout_height=”match_parent”/>

 

<FrameLayout

android:id=”@+id/fab_post”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_gravity=”bottom|right”

android:layout_marginBottom=”16dp”

android:layout_marginRight=”16dp”

android:background=”@drawable/fab_post” />

 

<!–<android.support.design.widget.FloatingActionButton–>

<!–android:src=”@drawable/fab_post”–>

<!–android:id=”@+id/fab_post”–>

<!–android:layout_width=”wrap_content”–>

<!–android:layout_height=”wrap_content”–>

<!–android:layout_gravity=”bottom|right”–>

<!–android:layout_marginBottom=”16dp”–>

<!–android:layout_marginRight=”16dp” />–>

 

</FrameLayout>

 

 

 

 

item_friend.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:padding=”16dp”

android:layout_width=”match_parent” android:layout_height=”wrap_content”>

 

<ImageView

android:id=”@+id/iv_img”

android:background=”#ffb115″

android:layout_width=”48dp”

android:layout_height=”48dp” />

 

<TextView

android:id=”@+id/tv_name”

android:textSize=”18sp”

android:layout_marginLeft=”8dp”

android:layout_centerVertical=”true”

android:layout_toRightOf=”@id/iv_img”

android:layout_toLeftOf=”@+id/tv_status”

android:layout_marginRight=”8dp”

android:lines=”1″

android:text=”겜팔이 이름”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

<TextView

android:id=”@+id/tv_status”

android:padding=”8dp”

android:background=”#ffb115″

android:layout_centerVertical=”true”

android:layout_alignParentRight=”true”

android:maxLines=”2″

android:maxWidth=”100dp”

android:text=”카톡안함”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content” />

 

 

 

</RelativeLayout>

 

 

 

 

item_post.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:orientation=”vertical”>

 

<ImageView

android:id=”@+id/iv_post_img”

android:layout_width=”match_parent”

android:layout_height=”wrap_content”

android:background=”#ffee58″

android:minHeight=”400dp” />

 

<RelativeLayout

android:layout_width=”match_parent”

android:layout_height=”37dp”

android:paddingLeft=”16dp”

android:paddingRight=”16dp”>

 

<CheckBox

android:id=”@+id/chk_like”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_centerVertical=”true”

android:button=”@drawable/chk_like” />

 

<TextView

android:id=”@+id/tv_like_count”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_centerVertical=”true”

android:layout_marginLeft=”8dp”

android:layout_toRightOf=”@id/chk_like”

android:text=”1234″ />

 

<View

android:id=”@+id/v_share”

android:layout_width=”24dp”

android:layout_height=”24dp”

android:layout_alignParentRight=”true”

android:layout_centerVertical=”true”

android:background=”#000000″ />

 

</RelativeLayout>

 

<View android:layout_width=”match_parent”

android:layout_height=”1dp”

android:background=”#e3e3e3″ />

 

<LinearLayout

android:layout_width=”match_parent”

android:layout_height=”37dp”

android:gravity=”center_vertical”

android:orientation=”horizontal”

android:paddingLeft=”16dp”

android:paddingRight=”16dp”>

 

<TextView

android:id=”@+id/tv_user_nickname”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:text=”ansta_”

android:textColor=”#28417a” />

 

<TextView

android:id=”@+id/tv_post_text”

android:layout_width=”wrap_content”

android:layout_height=”wrap_content”

android:layout_marginLeft=”4dp”

android:text=”불꽃놀이했어요~” />

 

</LinearLayout>

 

</LinearLayout>

 

 

 

 

drawable-xxhdpi/chk_like.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<selector xmlns:android=”http://schemas.android.com/apk/res/android”>

<item android:drawable=”@drawable/heart_bt” android:state_checked=”false” />

<item android:drawable=”@drawable/heart_bt_on” android:state_checked=”true” />

</selector>

 

 

 

 

fab_post.xml

 

<?xml version=”1.0″ encoding=”utf-8″?>

<selector xmlns:android=”http://schemas.android.com/apk/res/android”>

<item android:drawable=”@drawable/upload_bt” android:state_pressed=”false” />

<item android:drawable=”@drawable/upload_bt_on” android:state_pressed=”true” />

</selector>

 

 

 

 

 

UUID 사용

 

 

uuid/UserUUID.java

 

import java.util.UUID;

 

public class UserUUID {

private static final String PREF_UUID = “PREF_UUID”;

private static final String PREF_UUID_KEY = “PREF_UUID_KEY”;

 

public static String getUserUUID(Activity activity) {

 

SharedPreferences sharedPreferences = activity.getSharedPreferences(PREF_UUID, Context.MODE_PRIVATE);

String user_id = sharedPreferences.getString(PREF_UUID_KEY, null);

 

if (user_id == null) {

user_id = UUID.randomUUID().toString();

 

SharedPreferences.Editor editor = sharedPreferences.edit();

editor.putString(PREF_UUID_KEY, user_id);

editor.commit();

}

 

return user_id;

}

 

public static String forceGetUserUUID(Activity activity) {

SharedPreferences sharedPreferences = activity.getSharedPreferences(PREF_UUID, Context.MODE_PRIVATE);

 

String user_id = UUID.randomUUID().toString();

 

SharedPreferences.Editor editor = sharedPreferences.edit();

editor.putString(PREF_UUID_KEY, user_id);

editor.commit();

 

return user_id;

}

}

 

 

 

MainActivity.java

 

public class MainActivity extends AppCompatActivity {

 

TextView textview_uuid;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

 

textview_uuid = findViewById(R.id.textview_uuid);

findViewById(R.id.button_force_uuid).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

String s = UserUUID.forceGetUserUUID(MainActivity.this);

textview_uuid.setText(s);

}

});

 

String uuid = UserUUID.getUserUUID(this);

textview_uuid.setText(uuid);

}

}

 

 

 

 

 

 

 

Related posts

Leave a Comment