ListViewAdapter 를 만드는 과정이다.
Android Studio 가 제공하는 자동완성 기능을 이용하여 기본적인 골격을 만들어보자.
private class ListViewAdapter extends BaseAdapter {
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
return null;
}
}
기본 코드가 만들어진다.
연결된 정보들이 없어서 return null, return 0 를 반환하는 걸로 기본 코드가 만들어진 것을 확인할 수 있다.
이 코드에 살을 붙여서 완성된 코드를 만들어야 한다.
리스트뷰는 일반 위젯(TextView등)이 아니라 선택 위젯이기 때문에 직접 데이터를 설정할수가 없다.
Adapter를 이용해야 하고, 이 Adapter에서 만들어주는 getView()를 이용해서 아이템을 표시한다.
리스트뷰는 어댑터를 사용하여 데이터를 표시하는 View이다.
먼저 MainActivity Class 전역변수를 선언한다.
private ArrayList<PesonData> personDataItem = null; // 데이터 리스트
private ListViewAdapter listViewAdapter = null; // 리스트뷰에 사용되는 ListViewAdapter
class ViewHolder { public LinearLayout child_layout; public ImageView personal_imageView; public TextView tv_name; public TextView tv_mobileNO; public TextView tv_officeNO; public Button chid_btn; }
private class ListViewAdapter extends BaseAdapter {
public ListViewAdapter() { }
@Override public int getCount() { return personDataItem.size(); // 데이터 개수 리턴 }
@Override public Object getItem(int position) { return personDataItem.get(position); // 지정한 위치(position)에 있는 데이터를 리턴 } @Override public long getItemId(int position) { return position; // 지정한 위치(position)에 있는 데이터 리턴 }
// position에 위치한 데이터를 화면에 출력하는데 사용될 View를 리턴 @Override public View getView(int position, View view, ViewGroup viewGroup) { ViewHolder viewHolder; final Context context = viewGroup.getContext();
// 화면에 표시될 View if(view == null){ viewHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.person_item,viewGroup,false);
view.setBackgroundColor(0x00FFFFFF); view.invalidate();
// 화면에 표시될 View 로부터 위젯에 대한 참조 획득 viewHolder.personal_imageView = (ImageView) view.findViewById(R.id.personal_Image); viewHolder.tv_name = (TextView) view.findViewById(R.id.child_name); viewHolder.tv_mobileNO = (TextView) view.findViewById(R.id.child_mobileNO); viewHolder.tv_officeNO = (TextView) view.findViewById(R.id.child_officeNO); viewHolder.chid_btn = (Button) view.findViewById(R.id.child_Btn);
view.setTag(viewHolder); } else { viewHolder = (ViewHolder) view.getTag(); }
// PersonData 에서 position 에 위치한 데이터 참조 획득 PesonData pesonData = personDataItem.get(position);
// 아이템 내 각 위젯에 데이터 반영 viewHolder.personal_imageView.setImageDrawable(pesonData.getIcon()); viewHolder.tv_name.setText(pesonData.getName()); viewHolder.tv_mobileNO.setText(PhoneNumberUtils.formatNumber(pesonData.getMobileNO())); viewHolder.tv_officeNO.setText(PhoneNumberUtils.formatNumber(pesonData.getOfficeNO()));
viewHolder.chid_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) {
} });
return view; }
// 아이템 데이터 추가를 위한 메소드 public void addItem(Drawable icon, String uid, String name, String mobileNO, String officeNO){ PesonData item = new PesonData(); item.setIcon(icon); item.setUid(uid); item.setName(name); item.setMobileNO(mobileNO); item.setOfficeNO(officeNO);
personDataItem.add(item); } } |
이제 전체 코드를 보자.
안드로이드가 기본 제공하는 getView() 와 비교할 수 있는 부분은 별도 색상으로 표기를 했다.
import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.telephony.PhoneNumberUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast;
import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public SharedPreferences settings; private ListView listView; // 리스트뷰 private EditText editText; private Button btn_search;
private ArrayList<PesonData> personDataItem = null; // 데이터 리스트 private ListViewAdapter listViewAdapter = null; // 리스트뷰에 사용되는 ListViewAdapter
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.my_listView); editText = (EditText) findViewById(R.id.et_text01);
// Adapter에 추가 데이터를 저장하기 위한 ArrayList personDataItem = new ArrayList<PesonData>(); // ArrayList 생성
// Adapter 생성 listViewAdapter = new ListViewAdapter();
listView.setAdapter(listViewAdapter); // 어댑터를 리스트뷰에 세팅 btn_search = (Button) findViewById(R.id.btn_search); btn_search.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { settings = getSharedPreferences("settings", Activity.MODE_PRIVATE); Uri.Builder builder = new Uri.Builder() .appendQueryParameter("search", editText.getText().toString().trim()) .appendQueryParameter("idx", "2"); // settings.getString("idx","") String postParams = builder.build().getEncodedQuery(); new getJSONData().execute(Value.IPADDRESS + "/get_json.php",postParams); } }); } class getJSONData extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... params) { try { return PHPComm.getJson(params[0],params[1]); } catch (Exception e) { return new String("Exception: " + e.getMessage()); } }
protected void onPostExecute(String result){ searchJSON=result; showList(); } }
// 서버 정보를 파싱하기 위한 변수 선언 String searchJSON; private static final String TAG_RESULTS="result"; private static final String TAG_UID = "uid"; // 서버 테이블의 실제 필드명 private static final String TAG_NAME = "name"; private static final String TAG_MobileNO ="mobileNO"; private static final String TAG_OfficeNO ="officeNO"; JSONArray peoples = null;
protected void showList() { try { JSONObject jsonObj = new JSONObject(searchJSON); peoples = jsonObj.getJSONArray(TAG_RESULTS);
personDataItem.clear(); // 서버에서 가져온 데이터 초기화 for(int i=0;i<peoples.length();i++){ JSONObject c = peoples.getJSONObject(i); String uid = c.getString(TAG_UID); String name = c.getString(TAG_NAME); String mobileNO = c.getString(TAG_MobileNO); String officeNO = c.getString(TAG_OfficeNO); Drawable myIcon = getResources().getDrawable(R.mipmap.ic_launcher); // 이미지는 임시처리
// 서버에서 가져온 데이터 저장 listViewAdapter.addItem(myIcon,uid,name,mobileNO,officeNO); }
runOnUiThread(new Runnable() { @Override public void run() { // 갱신된 데이터 내역을 어댑터에 알려줌 listViewAdapter.notifyDataSetChanged(); } });
} catch (JSONException e) { e.printStackTrace(); } }
class ViewHolder { public LinearLayout child_layout; public ImageView personal_imageView; public TextView tv_name; public TextView tv_mobileNO; public TextView tv_officeNO; public Button chid_btn; }
private class ListViewAdapter extends BaseAdapter {
public ListViewAdapter() { }
@Override public int getCount() { return personDataItem.size(); // 데이터 개수 리턴 }
@Override public Object getItem(int position) { return personDataItem.get(position); }
// 지정한 위치(position)에 있는 데이터 리턴 @Override public long getItemId(int position) { return position; }
// position에 위치한 데이터를 화면에 출력하는데 사용될 View를 리턴 @Override public View getView(int position, View view, ViewGroup viewGroup) { ViewHolder viewHolder; final Context context = viewGroup.getContext();
// 화면에 표시될 View if(view == null){ viewHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.person_item,viewGroup,false);
view.setBackgroundColor(0x00FFFFFF); view.invalidate();
// 화면에 표시될 View 로부터 위젯에 대한 참조 획득 viewHolder.personal_imageView = (ImageView) view.findViewById(R.id.personal_Image); viewHolder.tv_name = (TextView) view.findViewById(R.id.child_name); viewHolder.tv_mobileNO = (TextView) view.findViewById(R.id.child_mobileNO); viewHolder.tv_officeNO = (TextView) view.findViewById(R.id.child_officeNO); viewHolder.chid_btn = (Button) view.findViewById(R.id.child_Btn);
view.setTag(viewHolder); } else { viewHolder = (ViewHolder) view.getTag(); }
// PersonData 에서 position 에 위치한 데이터 참조 획득 PesonData pesonData = personDataItem.get(position);
// 아이템 내 각 위젯에 데이터 반영 viewHolder.personal_imageView.setImageDrawable(pesonData.getIcon()); viewHolder.tv_name.setText(pesonData.getName()); viewHolder.tv_mobileNO.setText(PhoneNumberUtils.formatNumber(pesonData.getMobileNO())); viewHolder.tv_officeNO.setText(PhoneNumberUtils.formatNumber(pesonData.getOfficeNO()));
viewHolder.chid_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) {
} });
return view; }
// 아이템 데이터 추가를 위한 메소드 public void addItem(Drawable icon, String uid, String name, String mobileNO, String officeNO){ PesonData item = new PesonData(); item.setIcon(icon); item.setUid(uid); item.setName(name); item.setMobileNO(mobileNO); item.setOfficeNO(officeNO);
personDataItem.add(item); } }
} |
잘 정리된 블로그를 참조하면서 테스트 해보고 내 스타일로 수정하고 컴파일 하면서 완성도를 높여가며 테스트중이다. 실제 서버와 연동하여 실제 활용할 수 있는 코드 중심으로 작성해보는 중이다.
ListViewAdapter 를 Activity Class 단위로 생성해서 사용하는 것이 다른 Class 파일을 만드는 것보다 이해도가 좋은 거 같다.
추가 테스트가 필요한 사항
- 사진 이미지를 가져와서 보여주는 것 해결사항
- 버튼 이미지 또는 이미지를 누르면 Event 처리하는 기능
첨부 코드는 http://link2me.tistory.com/1250 파일에서 달라진 파일만 첨부했다.
json_demo_customListView.zip