728x90

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


블로그 이미지

Link2Me

,