티스토리 뷰
ListView 리스트뷰 실습
프로젝트를 생성하여 bulid.gradle에서 minSdkVersion을 16으로 변경하였다.
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.ktds.jmj.customlistview"
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.android.support:appcompat-v7:23.0.0'
}
사용할 리스트뷰를 생성하고
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"
android:orientation="vertical"
tools:context="com.ktds.jmj.customlistview.MainActivity">
<ListView
android:id="@+id/lvArticleListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
제목과 글쓴이를 담고 있는 item_list.xml을 생성한다.
item_list.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="match_parent">
<TextView
android:text="Message"
android:textColor="#F3F3F3"
android:background="#333333"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"/>
<TextView
android:id="@+id/tvSubject"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="subject"
android:textSize="20dp"
android:textColor="#000000"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:paddingBottom="3dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvAuthor"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Author"
android:paddingLeft="5dp"
android:layout_weight="9"/>
<TextView
android:id="@+id/tvHitCount"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="999"
android:layout_weight="1"
android:gravity="right"
android:paddingRight="5dp"/>
</LinearLayout>
</LinearLayout>
제목, 글쓴이 조회수를 담을 VO 클래스를 만들고, 생성자와 Getter, Setter을 만든다.
ArticleVO.java
package com.ktds.jmj.customlistview;
import java.io.Serializable;
/**
* Created by 206-020 on 2016-06-14.
*/
//
public class ArticleVO implements Serializable {
// Alt + Insert
private String subject;
private String author;
private String hitCount;
public ArticleVO(String subject, String author, String hitCount) {
this.subject = subject;
this.author = author;
this.hitCount = hitCount;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getHitCount() {
return hitCount;
}
public void setHitCount(String hitCount) {
this.hitCount = hitCount;
}
}
데이터를 불러오는 가장 효율적인 방법은 홀더를 이용한 방법이다.
MainActivity
package com.ktds.jmj.customlistview;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.ktds.jmj.customlistview.facebook.Facebook;
import com.restfb.types.Post;
import java.util.List;
public class MainActivity extends ActionBarActivity {
private ListView lvArticleList;
private Facebook facebook;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
lvArticleList = (ListView) findViewById(R.id.lvArticleListView);
facebook = new Facebook(this);
facebook.auth(new Facebook.After() {
@Override
public void doAfter(Context context) {
// 인증이 끝나면 동작
setTimeLine();
}
});
lvArticleList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(view.getContext(), SubActivity.class);
String articleId = ( (Post) lvArticleList.getAdapter().getItem(i)).getId();
Log.d("FACEBOOK", articleId);
intent.putExtra("articleId", articleId);
startActivity(intent);
}
});
}
/**
* Action Bar 에 메뉴를 생성한다.
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.list_menu, menu);
// 검색 기능 활성화
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
// 검색 버튼 가져옴
MenuItem searchButton = menu.findItem(R.id.searchButton);
// 검색 버튼 클릭 했을 때 SearchView 를 가져온다.
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchButton);
// 검색 힌트를 설정한다.
searchView.setQueryHint("검색어를 입력하세요.");
// searchView 를 검색 가능한 위젯으로 설정한다.
searchView.setSearchableInfo(searchManager.getSearchableInfo( getComponentName() ));
//두 가지 검색 방법 (클릭 했을 때와 입력할 때)
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
/**
* 검색 버튼을 클릭했을 때 동작하는 이벤트
* @param s
* @return
*/
@Override
public boolean onQueryTextSubmit(String s) {
Intent intent = new Intent(MainActivity.this, SearchActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
//s 파라미터는 입력된 검색어
intent.putExtra("query", s);
startActivity(intent);
return true;
}
/**
* 검색어를 입력할 때 동장하는 이벤트
* @param s
* @return
*/
@Override
public boolean onQueryTextChange(String s) {
return false;
}
});
return true;
}
/**
* 메뉴 아이템을 클릭했을 때 발생되는 이벤트
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if ( id == R.id.newPost ){
Intent intent = new Intent(this, WritePostActivity.class);
// intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivityForResult(intent, 1000);
// Toast.makeText(MainActivity.this, " 새 글 등록 버튼을 클릭했습니다.", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if ( requestCode == 1000 && resultCode == RESULT_OK ){
setTimeLine();
}
}
public void setTimeLine() {
if( facebook.isLogin() ){
// .... timeLine 가져오기
facebook.getTimeLine(new Facebook.TimelineSerializable() {
@Override
public void serialize(final List<Post> posts) {
handler.post(new Runnable() {
@Override
public void run() {
lvArticleList.setAdapter(new ArticleListViewAdapter(MainActivity.this, posts));
}
});
}
});
}
}
private class ArticleListViewAdapter extends BaseAdapter {
/**
* ListView 에 Item을 셋팅할 요청자의 객체가 들어감.
*/
private Context context;
private Post article;
/**
* ListView에 셋팅할 Item 정보들.
*/
private List<Post> articleList;
public ArticleListViewAdapter(Context context, List<Post> articleList) {
this.context = context;
this.articleList = articleList;
}
/**
* 아이템의 속성에 따라서 보여질 Item Layout을 정해준다.
* @param position
* @return
*/
@Override
public int getItemViewType(int position) {
// return super.getItemViewType(position);
/**
* 만약, Message가 null 이 아니라면 list_item_message 를 보여주고,
* Story 가 null 이 아니라면 list_item_story 를 보여주고,
* link 가 null 이 아니라면 list_item_link 를 보여준다.
*/
article = (Post) getItem(position);
if ( article.getMessage() != null && article.getMessage().length() > 0 ){
return 0;
}
else if ( article.getStory() != null && article.getStory().length() > 0 ){
return 1;
}
else if ( article.getLink() != null && article.getLink().length() > 0 ){
return 2;
}
return 0;
}
public int getLayoutType( int index ){
if ( index == 0 ) {
return R.layout.list_item_message;
}
else if ( index == 1 ) {
return R.layout.list_item_story;
}
else if ( index == 2 ){
return R.layout.list_item_link;
}
return -1;
}
/**
* Item Layout 의 개수를 정한다.
* @return
*/
@Override
public int getViewTypeCount() {
return 3;
}
/**
* ListView에 셋팅할 아이템들의 수
* @return
*/
@Override
public int getCount() {
return this.articleList.size();
}
/**
* position 번째 Item 정보를 가져옴.
* @param position
* @return
*/
@Override
public Object getItem(int position) {
return this.articleList.get(position);
}
/**
* Item Index를 가져옴
* Item Index == position
* @param position
* @return
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* ListView에 Item을 셋팅함
* @param position : 현재 보여질 Item의 Index , 0부터 getCount() 까지 증가함
* @param convertView : ListView 의 Item Cell 객체를 가져옴.
* @param parent : ListView
* @return
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemHolder holder = null;
int layoutType = getItemViewType(position);
//가장 효율적인 방법
if (convertView == null) {
// Item Cell에 Layout을 적용시킬 Inflater 객체
LayoutInflater inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
// Item Cell 에 Layout을 적용시킨다.
// false는 덮어쓸것이냐 말것이냐 대부분 false 를 쓴다.
convertView = inflater.inflate(getLayoutType(layoutType), parent, false);
holder = new ItemHolder();
if( layoutType == 0 ) {
holder.tvSubject = (TextView) convertView.findViewById(R.id.tvSubject);
holder.tvAuthor = (TextView) convertView.findViewById(R.id.tvAuthor);
holder.tvHitCount = (TextView) convertView.findViewById(R.id.tvHitCount);
}
else if( layoutType == 1 ) {
holder.tvSubject = (TextView) convertView.findViewById(R.id.tvSubject);
}
else if( layoutType == 2 ){
holder.tvSubject = (TextView) convertView.findViewById(R.id.tvSubject);
}
convertView.setTag(holder);
}
else {
holder = (ItemHolder) convertView.getTag();
}
article = (Post) getItem(position);
if( layoutType == 0 ){
holder.tvSubject.setText(article.getMessage());
holder.tvAuthor.setText(article.getFrom().getName());
if ( article.getLikes() == null )
holder.tvHitCount.setText("0");
else
holder.tvHitCount.setText(article.getLikes().getData().size() + "");
}
else if ( layoutType == 1 ){
holder.tvSubject.setText(article.getStory());
}
else if ( layoutType == 2 ){
holder.tvSubject.setText(article.getLink());
holder.tvSubject.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
Intent intent = new Intent ( Intent.ACTION_VIEW, Uri.parse(article.getLink()));
startActivity(intent);
}
});
}
return convertView;
}
}
private class ItemHolder {
public TextView tvSubject;
public TextView tvAuthor;
public TextView tvHitCount;
}
}
ItemHolder 를 사용하여 한 Cell에 사용되는 것들을 매번 생성하는 대신 필요할때 꺼내서 사용한다.
홀더를 사용하면 메모리 낭비를 줄일 수 있다.
'Android' 카테고리의 다른 글
[Android] Fragment 예제 (PagerSlidingTabStrip , TabLayout ) (4) | 2016.08.03 |
---|---|
[Android] APK 생성 (0) | 2016.07.29 |
[Android] 웹에 요청하기 (0) | 2016.07.26 |
[Android] 항목 선택 MultiChoiceItems, SingleChoiceItems (1) | 2016.07.25 |
[Android] 권한 획득 (0) | 2016.07.25 |
- Total
- Today
- Yesterday
- 자바
- order by
- controller
- table
- INSERT
- AlertDialog.Builder
- DP
- sort
- onBackPressed
- onPostExecute
- maven
- list
- DFS
- 안드로이드 비콘
- Baekjoon Online Judege
- mybatis
- RequestMapping
- 예외처리
- java
- algorithm
- restfb
- REDIRECT
- 안드로이드 스튜디오
- jsp
- indexOf
- servlet
- Spring
- boj
- 이클립스
- BFS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |