Android

안드로이드 5기 2017년 강의 정리 1 (오준석의 생존코딩)

 

 

https://www.youtube.com/watch?v=MjtlPTUUL74&list=PLxTmPHxRH3VWSF7kMcsIaTglWUJZpWeQ9&index=1

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki

MyFirstAndroidApp5ki-master

 

1일차

2일차 RelativeLayout

3일차 커피앱 코딩

5일차 액티비티끼리 데이터 주고 받기

6일차 암시적 인텐트와 인텐트 필터

7일차 옵션 메뉴

8일차 WebView

9일차 ArrayAdapter, SimpleAdapter

10일차 BaseAdapter

 


 

 1. 1일차

 

textSize 는 sp 를 써라 (시스템에서 textSize 변경시 같이 변경됨)

길이는 dp 를 써라.

ImageView 의 scaleType 은 centerCrop 권장

리소스 파일 이름은 숫자로 시작하면 안되고 소문자로만 구성해야한다.

drawable 폴더는 메모리를 더 사용하므로 drawable-hdpi 폴더를 만들어서 사용하라.

 

# LinearLayout 에서 가중치(weight) 주기

가중치를 줄 속성에 0dp 에 준다.
LinearLayout 에 android:weightSum=”5″ 를 주면 5/5 가중치를 만듦

 

layout_height=”0dp”
layout_weight=”1″ // 1번 view (1/5)

layout_height=”0dp”
layout_weight=”1″ // 2번 view (1/5)

layout_height=”0dp”
layout_weight=”3″ // 3번 view (3/5)

 

 


 

 2. 2일차

 

RelativeLayout

 

글을 오른쪽부터 쓰는 나라를 위해서 Left, Right 가 아니라 Start, End 를 써라.

 

layout_toLeftOf
layout_above
layout_toRightOf
layout_below
layout_toStartOf
layout_toEndOf

layout_alignParentLeft
layout_alignParentTop
layout_alignParentRight
layout_alignParentBottom
layout_centerHorizontal
layout_centerVertical
layout_centerInParent
layout_alignParentStart
layout_alignParentEnd

layout_alignLeft
layout_alignTop
layout_alignRight
layout_alignBottom
layout_alignBaseline

 

RelativeLayout (개발자를 위한 레시피)
https://recipes4dev.tistory.com/126

 

 


 

 3. 3일차 커피앱 코딩

 

Live Templates

File – Settings – Editor – Live Templates

ld : Log.d(TAG, “$cursor”);  // statement, Reformat according to style

public static final String TAG = MainActivity.class.getSimpleName();

 

Andorid Logcat 색상 지정

File – Settings – Editor – Color Scheme – Android Logcat

 


 

 4. 5일차 액티비티끼리 데이터 주고 받기

 

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/OrderCheckActivity.java

 

# 암시적 인텐트를 검색하려면 common intents 를 검색하라.

https://developer.android.com/guide/components/intents-common#java

 

# 암시적 인텐트를 사용해서 이메일 보내기

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // only email apps should handle this
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

 

# 암시적 인텐트를 사용해서 전화 걸기

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

public void dialPhoneNumber(String phoneNumber) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

 


 

4. 안드로이드5일차 액티비티끼리 데이터 주고 받기 2

 

https://developer.android.com/training/basics/intents/result#java

 

# StartActivityForResultActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/StartActivityForResultActivity.java

 

# TargetActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/TargetActivity.java

 

 

4가지 컴포넌트는 AndoridManifest.xml 에 선언되어야 사용할 수 있다.

 

# 보내는 액티비티

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(this, TargetActivity.class);
        intent.putExtra("value", mValueEditText.getText().toString());
        //  startActivity(intent);
        // 주거니 받거니
        startActivityForResult(intent, REQUEST_CODE_EXAMPLE);
    }

    // 받을 때 호출 되는 콜백 메서드
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE_EXAMPLE && resultCode == RESULT_OK && data != null) {
            Log.d(TAG, "onActivityResult: " + requestCode);
            Log.d(TAG, "onActivityResult: " + resultCode);
            Log.d(TAG, "onActivityResult: " + data);
            String result = data.getStringExtra("result");
            int value = data.getIntExtra("int", -1);
            Toast.makeText(this, result + ", int: " + value, Toast.LENGTH_SHORT).show();
        } else if (requestCode == REQUEST_CODE_NEW_MEMO) {

        } else if (requestCode == REQUEST_CODE_UPDATE_MEMO) {

        }
    }

 

# 받는 액티비티

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_target);

    if (getIntent() != null) {
        String value = getIntent().getStringExtra("value");
        mValueTextView.setText(value);
    }
}

@Override
public void onClick(View v) {
    // 결과 전달
    Intent intent = new Intent();
    intent.putExtra("result", "이것은 내가 지정한 문구다");
    intent.putExtra("int", 50);

    setResult(RESULT_OK, intent);
    finish();
}

 


 

 4. 안드로이드5일차 연습문제 풀이

 

# IntentExamActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/IntentExamActivity.java

 

# IntentExamActivity2.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/IntentExam2Activity.java

 

public class IntentExamActivity extends AppCompatActivity implements View.OnClickListener {

    public static final int REQUEST_CODE = 1000;
    private EditText mIdEditText;
    private EditText mPasswordEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_exam);

        mIdEditText = (EditText) findViewById(R.id.id_edit);
        mPasswordEditText = (EditText) findViewById(R.id.password_edit);

        findViewById(R.id.login_button).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(this, IntentExam2Activity.class);
        intent.putExtra("id", mIdEditText.getText().toString());
        intent.putExtra("password", mPasswordEditText.getText().toString());

        startActivityForResult(intent, REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE
                && resultCode == RESULT_OK
                && data != null) {
            String text = data.getStringExtra("result");
            Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
        }
    }
}

 

public class IntentExam2Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_exam2);

        if (getIntent() != null) {
            String id = getIntent().getStringExtra("id");
            String password = getIntent().getStringExtra("password");

            Toast.makeText(this, "id = " + id + ", pw = " + password, Toast.LENGTH_SHORT).show();
        }
    }

    public void onClick(View view) {
        String text = ((Button) view).getText().toString();

        Intent intent = new Intent();
        intent.putExtra("result", text);

        setResult(RESULT_OK, intent);
        finish();
    }
}

 

 


 

5. 6일차 암시적 인텐트와 인텐트 필터

 

# 공통 인텐트

https://developer.android.com/guide/components/intents-common#java

 

# ImplicitActivity.java

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/ImplicitActivity.java

 

ActionBar 는 오래전에 나와서 클릭도 안되고 활용성이 없어서 사용을 안한다.
이 후에 활용성이 좋은 Toolbar 가 나왔다.

 

public class ImplicitActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText mPhoneEditText;
    private EditText mUrlEditText;

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

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });


        mPhoneEditText = (EditText) findViewById(R.id.phone_edit);
        mUrlEditText = (EditText) findViewById(R.id.url_edit);

        findViewById(R.id.phone_button).setOnClickListener(this);
        findViewById(R.id.url_button).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.phone_button:
                String phoneNumber = mPhoneEditText.getText().toString();
                dialPhone(phoneNumber);
                break;
            case R.id.url_button:
                String url = mUrlEditText.getText().toString();
                showUrl(url);
                break;
        }
    }

    private void showUrl(String url) {
        if (!url.startsWith("http://")) {
            url = "http://" + url;
        }
        Uri webpage = Uri.parse(url);
        Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        }
    }

    private void dialPhone(String phoneNumber) {
        Intent intent = new Intent(Intent.ACTION_DIAL);
        intent.setData(Uri.parse("tel:" + phoneNumber));
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        } else {
            Toast.makeText(this, "수행할 앱이 없어요", Toast.LENGTH_SHORT).show();
        }
    }
}

 


 

5. 6일차 로그인 연습문제 풀이

 

# SignUpExamActivity.java

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/SignUpExamActivity.java

 

# SignUpExamTargetActivity.java

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/SignUpExamTargetActivity.java

 

public class SignUpExamActivity extends AppCompatActivity implements View.OnClickListener {

    public static final int REQUEST_CODE_SIGN_UP = 1000;
    private EditText mIdEditText;
    private EditText mPassEditText;
    private EditText mPass2EditText;
    private EditText mEmailEditText;
    private RadioGroup mGenderGroup;

    private ArrayList<EditText> mEditTextList;
    private String mGenger;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sign_up_exam);

        mEditTextList = new ArrayList<>();

        mIdEditText = (EditText) findViewById(R.id.id_edit);
        mPassEditText = (EditText) findViewById(R.id.pass_edit);
        mPass2EditText = (EditText) findViewById(R.id.pass2_edit);
        mEmailEditText = (EditText) findViewById(R.id.email_edit);

        mEditTextList.add(mIdEditText);
        mEditTextList.add(mPassEditText);
        mEditTextList.add(mPass2EditText);
        mEditTextList.add(mEmailEditText);

        mGenderGroup = (RadioGroup) findViewById(R.id.gender_group);
        mGenderGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                mGenger = ((RadioButton)findViewById(checkedId)).getText().toString();
            }
        });

        findViewById(R.id.reset_button).setOnClickListener(this);
        findViewById(R.id.sign_up_button).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.reset_button:
                reset();
                break;
            case R.id.sign_up_button:
                signUp();
                break;
        }
    }


    private boolean isValid() {
        for (EditText editText : mEditTextList) {
            if (TextUtils.isEmpty(editText.getText().toString())) {
                return false;
            }
        }

        if (mGenderGroup.getCheckedRadioButtonId() == -1) {
            return false;
        }

        return true;
    }

    private void signUp() {
        if (!isValid()) {
            Toast.makeText(this, "모두 입력 해 주셔야 합니다", Toast.LENGTH_SHORT).show();
        } else if (!isValidPassword()) {
            Toast.makeText(this, "비밀번호가 다릅니다", Toast.LENGTH_SHORT).show();
        } else {
            // 가입
            Intent intent = new Intent(this, SignUpExamTargetActivity.class);
            intent.putExtra("id", mIdEditText.getText().toString());
            intent.putExtra("pass", mPassEditText.getText().toString());
            intent.putExtra("email", mEmailEditText.getText().toString());
            intent.putExtra("gender", mGenger);

            startActivityForResult(intent, REQUEST_CODE_SIGN_UP);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE_SIGN_UP &&
                resultCode == RESULT_OK) {
            Toast.makeText(this, "확인 버튼을 누르셨습니다", Toast.LENGTH_SHORT).show();
        }
    }

    private boolean isValidPassword() {
        return mPassEditText.getText().toString().equals(mPass2EditText.getText().toString());
    }

    private void reset() {
        for (EditText editText : mEditTextList) {
            editText.setText("");
        }

        mGenderGroup.clearCheck();
    }
}

 

 

public class SignUpExamTargetActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sign_up_exam_target);

        if (getIntent() != null) {
            String id = getIntent().getStringExtra("id");
            String pass = getIntent().getStringExtra("pass");
            String email = getIntent().getStringExtra("email");
            String gender = getIntent().getStringExtra("gender");

            String result = String.format("아이디 : %s\n비밀번호 : %s\n이메일 : %s     성별 : %s",
                    id,
                    pass,
                    email,
                    gender);

            TextView resultTextView = (TextView) findViewById(R.id.result_text);
            resultTextView.setText(result);
        }

        findViewById(R.id.ok_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setResult(RESULT_OK);
                finish();
            }
        });
    }
}

 

 


 

6. 7일차 옵션 메뉴

 

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

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/MainActivity.java

https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/menu/menu_main.xml

 

 

# menu/menu_main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_setting"
        android:icon="@mipmap/ic_launcher"
        android:title="설정"
        app:showAsAction="always" />
    <item
        android:id="@+id/action_menu2"
        android:title="Item2" />
    <item
        android:id="@+id/action_menu3"
        android:title="Item3" />
</menu>

 

# MainActivity.java

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_setting:
            Toast.makeText(this, "설정 아직 미구현", Toast.LENGTH_SHORT).show();
            return true;
        case R.id.action_menu2:
            sound();
            return true;
        case R.id.action_menu3:
            startChronometer();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

 

 

private Chronometer mChronometer;

...
// onCreate() 안에 작성..
mChronometer = (Chronometer) findViewById(R.id.timer);
mChronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
    @Override
    public void onChronometerTick(Chronometer chronometer) {
        Log.d(TAG, "onChronometerTick: " + chronometer.getText().toString());
        sound();
    }
});

 

 

private void startChronometer() {
    mChronometer.setBase(SystemClock.elapsedRealtime());
    mChronometer.start();
}

private void sound() {
    MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.monkey);
    mediaPlayer.start();
}

 

 


 

7. 8일차 WebView

 

# WebBrowserActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/WebBrowserActivity.java

 

# activity_web_browser.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/activity_web_browser.xml

 

public class WebBrowserActivity extends AppCompatActivity {

    private EditText mUrlEditText;
    private WebView mWebView;

    private Button mSearchButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_browser);

        mUrlEditText = (EditText) findViewById(R.id.url_edit);
        mWebView = (WebView) findViewById(R.id.web_view);

        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        // 일반적
//        mWebView.setWebViewClient(new WebViewClient());

        // 기능 확장
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);

                Toast.makeText(WebBrowserActivity.this, "로딩 완료", Toast.LENGTH_SHORT).show();
            }
        });

        mSearchButton = (Button) findViewById(R.id.search_btn);
        mSearchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mWebView.loadUrl(mUrlEditText.getText().toString());
            }
        });

        // 키보드 이벤트 검출
        mUrlEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                    // 버튼을 코드로 누르기
                    mSearchButton.callOnClick();

                    // 키보드 내리기
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(mUrlEditText.getWindowToken(), 0);
                }
                return true;
            }
        });

    }

    // 뒤로 가기 키 캐치
    @Override
    public void onBackPressed() {
        if (mWebView.canGoBack()) {
            mWebView.goBack();
        } else {
            super.onBackPressed();
        }
    }
}

 


 

– 9일차 ArrayAdapter, SimpleAdapter

 

# ListViewActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/ListViewActivity.java

# activity_list_view.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/activity_list_view.xml

 

 

 


 

 # ArrayAdapter, SimpleAdapter (구글 검색)

 

# ArrayAdapter

ArrayList<String> mDataList = new ArrayList<>();

for (int i = 0; i < 50; i++) {
    mDataList.add("item " + i);
}

ArrayAdapter<String> adapter =
        new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mDataList);

ListView listView = findViewById(R.id.listview);
listView.setAdapter(adapter);

listView.setOnItemClickListener((parent, view, position, id) -> {
    String selected_item = (String)parent.getItemAtPosition(position);

    mDataList.remove(selected_item);

    adapter.notifyDataSetChanged();
});

 

# SimpleAdapter

ListView listView = findViewById(R.id.listview);
ArrayList<HashMap<String, String>> dataList =  new ArrayList<>();

HashMap<String, String> mapData = new HashMap<>();
mapData.put("name", "홍길동");
mapData.put("city", "광주광역시");
dataList.add(mapData);

mapData = new HashMap<String, String>();
mapData.put("name", "임꺽정");
mapData.put("city", "서울특별시");
dataList.add(mapData);

mapData = new HashMap<String, String>();
mapData.put("name", "김두한");
mapData.put("city", "대전광역시");
dataList.add(mapData);

SimpleAdapter adapter = new SimpleAdapter(this, dataList,
                android.R.layout.simple_list_item_2,
                new String[] {"name", "city"},
                new int[] {android.R.id.text1, android.R.id.text2});
listView.setAdapter(adapter);

 

# ArrayList, ArrayAdapter와 ListView – 1. 기본적인 사용 방법
https://webnautes.tistory.com/1190

# Using an ArrayAdapter with ListView
https://guides.codepath.com/android/Using-an-ArrayAdapter-with-ListView

 

# [Android] ListView와 SimpleAdapter
https://m.blog.naver.com/draming/20158837275

# Custom SimpleAdapter Tutorial With Example In Android Studio
https://abhiandroid.com/ui/custom-simpleadapter.html

 

 


 

8. 10일차 BaseAdapter

 

# WeatherActivity.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/activities/WeatherActivity.java

# adapters/WeatherAdapter.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/adapters/WeatherAdapter.java

# models/Weather.java
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/java/com/example/myapplication/models/Weather.java

# item_weather.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/item_weather.xml

# activity_weather.xml
https://github.com/suwonsmartapp/MyFirstAndroidApp5ki/blob/master/app/src/main/res/layout/activity_weather.xml

 

 

# 사진 파일은 drawable-hdpi 폴더에 넣어라. drawable 폴더에 넣으면 메모리를 더 많이 차지한다.

# 뷰홀더 사용 이유
listview 는 뷰를 재사용한다.
뷰를 재사용할 때마다 findViewById 를 하게되면 효율성이 떨어지므로 뷰홀더를 사용한다.

# AdapterView 는 ListView, GridView, Spinner 세 개를 주로 사용한다.

 

# item_weather.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="8dp">

    <ImageView
        android:id="@+id/weather_image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/ic_launcher" />

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

        <TextView
            android:id="@+id/location_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="지역"
            android:textSize="36sp" />

        <TextView
            android:id="@+id/temperature_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:text="기온"
            android:textSize="24sp" />
    </LinearLayout>

</LinearLayout>

 

# activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_weather"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Spinner
        android:id="@+id/spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <GridView
        android:id="@+id/grid_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:numColumns="3" />

</LinearLayout>

 

# models/Weather.java

public class Weather {
    private int imageRes;
    private String weather;
    private String country;
    private String temperature;

    public Weather(int imageRes, String country, String temperature) {
        this.imageRes = imageRes;
        this.country = country;
        this.temperature = temperature;
    }

    public int getImageRes() {
        return imageRes;
    }

    public void setImageRes(int imageRes) {
        this.imageRes = imageRes;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getTemperature() {
        return temperature;
    }

    public void setTemperature(String temperature) {
        this.temperature = temperature;
    }

    public String getWeather() {
        return weather;
    }

    public void setWeather(String weather) {
        this.weather = weather;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Weather{");
        sb.append("country='").append(country).append('\'');
        sb.append(", imageRes=").append(imageRes);
        sb.append(", weather='").append(weather).append('\'');
        sb.append(", temperature='").append(temperature).append('\'');
        sb.append('}');
        return sb.toString();
    }
}

 

# adapters/WeatherAdapter.java

public class WeatherAdapter extends BaseAdapter {
    private static final String TAG = WeatherAdapter.class.getSimpleName();
    private Context mContext;
    private List<Weather> mData;

    public WeatherAdapter(Context context, List<Weather> data) {
        mContext = context;
        mData = data;
    }

    // 아이템 갯수
    @Override
    public int getCount() {
        return mData.size();
    }

    // position번째 아이템
    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    // postion번째 id
    @Override
    public long getItemId(int position) {
        return position;
    }

    // position번째의 레이아웃
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        // convertView : 재사용 되는 뷰
        if (convertView == null) {
            viewHolder = new ViewHolder();

            // 뷰를 새로 만들 때
            convertView = LayoutInflater.from(mContext)
                    .inflate(R.layout.item_weather, parent, false);

            // 레이아웃 들고 오기
            ImageView imageView = convertView.findViewById(R.id.weather_image);
            TextView locationTextView = convertView.findViewById(R.id.location_text);
            TextView temperatureTextView = convertView.findViewById(R.id.temperature_text);

            // 뷰 홀더에 넣는다
            viewHolder.weatherImage = imageView;
            viewHolder.locationTextView = locationTextView;
            viewHolder.temperatureTextView = temperatureTextView;

            convertView.setTag(viewHolder);
        } else {
            // 재사용 할 때
            viewHolder = (ViewHolder) convertView.getTag();
        }

        Log.d(TAG, "getView: " + position);

        // 데이터
        Weather weather = mData.get(position);

        // 화면에 뿌리기
        viewHolder.weatherImage.setImageResource(weather.getImageRes());
        viewHolder.locationTextView.setText(weather.getCountry());
        viewHolder.temperatureTextView.setText(weather.getTemperature());

        // 홀수 줄은 빨간 색
        if (position % 2 == 1) {
            convertView.setBackgroundColor(Color.RED);
        } else {
            convertView.setBackgroundColor(Color.WHITE);
        }

        // 클릭 된 아이템이면 노란색
        if (mSeletedPosition == position) {
            convertView.setBackgroundColor(Color.YELLOW);
        }

        return convertView;
    }

    // -1이면 선택된게 없다
    private int mSeletedPosition = -1;

    public void setSelect(int position) {
        mSeletedPosition = position;
    }

    // findViewById로 가져온 View 들을 보관
    private static class ViewHolder {
        ImageView weatherImage;
        TextView locationTextView;
        TextView temperatureTextView;
    }
}

 

# MainActivity.java

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {

    private ListView mListView;
    private GridView mGridView;
    private Spinner mSpinner;
    private WeatherAdapter mAdapter;
    private List<Weather> mWeatherList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mListView = findViewById(R.id.list_view);
        mGridView = findViewById(R.id.grid_view);
        mSpinner = findViewById(R.id.spinner);

        // 날씨 데이터
        mWeatherList = new ArrayList<>();
        mWeatherList.add(new Weather(R.drawable.sunny, "수원", "27도"));
        mWeatherList.add(new Weather(R.drawable.blizzard, "안양", "23도"));
        mWeatherList.add(new Weather(R.drawable.cloudy, "안산", "24도"));
        mWeatherList.add(new Weather(R.drawable.rainy, "평택", "22도"));
        mWeatherList.add(new Weather(R.drawable.snow, "서울", "26도"));
        mWeatherList.add(new Weather(R.drawable.sunny, "부산", "21도"));
        mWeatherList.add(new Weather(R.drawable.sunny, "도쿄", "10도"));
        mWeatherList.add(new Weather(R.drawable.sunny, "워싱턴", "5도"));
        mWeatherList.add(new Weather(R.drawable.snow, "평양", "6도"));
        mWeatherList.add(new Weather(R.drawable.snow, "베이징", "12도"));
        mWeatherList.add(new Weather(R.drawable.rainy, "수원", "49도"));
        mWeatherList.add(new Weather(R.drawable.rainy, "수원", "27도"));
        mWeatherList.add(new Weather(R.drawable.blizzard, "수원", "27도"));
        mWeatherList.add(new Weather(R.drawable.blizzard, "수원", "27도"));
        mWeatherList.add(new Weather(R.drawable.sunny, "수원", "27도"));
        mWeatherList.add(new Weather(R.drawable.sunny, "수원", "27도"));
        mWeatherList.add(new Weather(R.drawable.sunny, "수원", "27도"));
        mWeatherList.add(new Weather(R.drawable.sunny, "수원", "27도"));

        // 어댑터
        mAdapter = new WeatherAdapter(this, mWeatherList);

        // 어댑터를 뷰에 설정
        mListView.setAdapter(mAdapter);
        mGridView.setAdapter(mAdapter);
        mSpinner.setAdapter(mAdapter);

        // 이벤트
        mListView.setOnItemClickListener(this);
        mListView.setOnItemLongClickListener(this);

        mGridView.setOnItemClickListener(this);
        mGridView.setOnItemLongClickListener(this);
    }


    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        mAdapter.setSelect(position);
        // 데이터가 변경됨을 알려줌 = 다시 그려라
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
        // 롱 클릭시 해당 아이템 삭제
        mWeatherList.remove(position);

        // 어댑터에 변경을 통지 = 다시 그려라
        mAdapter.notifyDataSetChanged();
        return true;
    }
}

 

 

Related posts

Leave a Comment