티스토리 뷰

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);

/**
* 만약, Messagenull 이 아니라면 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;
}

/**
* ListViewItem을 셋팅함
* @param position : 현재 보여질 ItemIndex , 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에 사용되는 것들을 매번 생성하는 대신 필요할때 꺼내서 사용한다.


홀더를 사용하면 메모리 낭비를 줄일 수 있다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
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
글 보관함