본문 바로가기

아옳옳의 코딩공부/아옳옳의 안드로이드스튜디오

2021-04-15안드로이드 스튜디오(어댑터 뷰 )

반응형

어댑터 뷰 

스크롤 뷰는 자신의 영역을 초과하여 배치된 자식 뷰를 스크롤 하며 볼 수 있다는 장점이 있다 . 

하지만 스크롤 전에 보이지 않는 자식의 뷰까지 미리 생성하고 그려두기 때문에 용량을 많이 차지하게 된다 

그 단점을 보안하고자 나온것이 어댑터 뷰이다 .

어댑터뷰는 미리 생성하지 않고 보여질때 생성한다. 

 

다른 뷰보다 어렵고 복잡하지만 일반적으로 앱을 구현하다보면 반드시 하나 이상의 어댑터뷰를 사용해야 하는 경우가 대부분이다 .

 

어댑터 뷰에는 크게 3가지가 있다 . ( 강사님왈 보통 베이스를 많이 사용하신다고 한다 내가 직접만들어 사용가능하기 때문에 ..... 하지만 나머지도 알아는 놔야 겠지? 

 

베이스 어댑터  : 내가 만들어서 사용하는것? 

어레이 어댑터 : 어레이리스트랑 비슷한 성격을 가지고 있어서 각종 메소드 사용가능 

심플어댑터  : 수정은 안되고 단순하게 보여줄때만 사용함 

코드로 이해하자

베이스어댑터 

public class BaseAdapterEx extends BaseAdapter // 이것을 상속받으면 getCount 와 getView 필요함
{
    Context  mContext  = null;
    ArrayList<Student> mData  = null;
    LayoutInflater  mLayoutInflater = null;

    public BaseAdapterEx( Context context, ArrayList<Student> data )
    {
        mContext = context;
        mData = data;
        mLayoutInflater = LayoutInflater.from(mContext); // 인플레이터
    }

    @Override
    public int getCount()// 이사이즈 만큼 리스트뷰 만들어 주겠다는 코드
    {
        return mData.size();
    }

    @Override
    public Student getItem( int position ) // 나중에 아이템 가져올때 사용하기 위한 코드 지금은 안씀
    {
        return mData.get( position );

    }

    @Override
    public long getItemId( int position ) // 나중에 아이디 가져올때 사용하기 위한 코드 지금은 안씀
    {
        return position;
    }

    class ViewHolder // 뷰홀더 클래스
    {
        TextView mNameTv;
        TextView mNumberTv;
        TextView mDepartmentTv;
    }

    @Override
    public View getView( int position, View convertView, ViewGroup parent ) // 겟뷰
    {
        View itemLayout = convertView; // convertView는 최적화 하기 위하여 사용
        ViewHolder  viewHolder = null;

        // 1. 어뎁터뷰가 재사용할 뷰를 넘겨주지 않은 경우에만 새로운 뷰를 생성한다.
        // ====================================================================
        if( itemLayout == null ) //. 1
        {
            itemLayout = mLayoutInflater.inflate(R.layout.list_view_item_layout, null);

            // View Holder를 생성하고 사용할 자식뷰를 찾아 View Holder에 참조시킨다.
            // 생성된 View Holder는 아이템에 설정해 두고, 다음에 아이템 재사용시
            // 참조한다.
            // ----------------------------------------------------------------
            viewHolder = new ViewHolder();

            viewHolder.mNameTv =  (TextView) itemLayout.findViewById( R.id.name_text );
            viewHolder.mNumberTv = (TextView) itemLayout.findViewById( R.id.number_text );
            viewHolder.mDepartmentTv = (TextView) itemLayout.findViewById( R.id.department_text );

            itemLayout.setTag( viewHolder );
            // ----------------------------------------------------------------
        }
        else
        {
            // 재사용 아이템에는 이전에 View Holder 객체를 설정해 두었다.
            // 그러므로 설정된 View Holder 객체를 이용해서 findViewById 함수를
            // 사용하지 않고 원하는 뷰를 참조할 수 있다.
            viewHolder = (ViewHolder)itemLayout.getTag();
        }
        // ====================================================================

        // 2. 이름, 학번, 학과 데이터를 참조하여 레이아웃을 갱신한다.
        // ====================================================================
        viewHolder.mNameTv.setText( mData.get( position ).mName );
        viewHolder.mNumberTv.setText( mData.get( position ).mNumber );
        viewHolder.mDepartmentTv.setText( mData.get( position ).mDepartment );
        // ====================================================================

        return itemLayout; // 아이템 레이아웃이나 뷰홀더나 가르키는것은 똑같다
    }

    public void add( int index, Student addData ) // 추가 메소드
    {
        mData.add( index, addData ); // 메인에서 보낸 추가 를 받아 어레이 리스트에 추가
        notifyDataSetChanged(); // 실시간으로 어댑터가 실행하지 않아서 어댑터에서 알려줘서 바꿔줌
    }

    public void delete( int index ) // 삭제 메소드
    {
        mData.remove( index );
        notifyDataSetChanged();
    }

    public void clear( ) // 클리어 메소드
    {
        mData.clear();
        notifyDataSetChanged();
    }
}

메인액티비티

public class MainActivity extends AppCompatActivity {

    ListView mListView = null;
    BaseAdapterEx mAdapter = null;
    ArrayList<Student> mData = null;

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

        mData = new ArrayList<Student>();

        for(int i = 0 ; i<100 ; i++){  //  실질적인 데이터를 어레이 리스트에 담기
            Student student = new Student();
            student.mName = "아옳이" + i;
            student.mNumber= "95000"+ i;
            student.mDepartment =  i +"대 멀록왕";

            mData.add(student);
        }

        mAdapter = new BaseAdapterEx(this , mData);  //BaseAdapter 생성 ( 컨택스트 정보와 데이터 넘겨줌 )
        mListView =(ListView)findViewById(R.id.list_view); // xml 리스트뷰 아이디 참조
        mListView.setAdapter(mAdapter); //리스트뷰에 어댑터 셋팅
    }


    public void onClick(View view) {

        switch (view.getId()){
            case R.id.add_btn:
                //에디트 택스트 생성
                EditText nameEt = (EditText)findViewById(R.id.name_edit);
                EditText numberEt = (EditText)findViewById(R.id.number_edit);
                EditText departmentEt = (EditText)findViewById(R.id.department_edit);

                Student addData = new Student();
                addData.mName = nameEt.getText().toString();
                addData.mNumber = numberEt.getText().toString();
                addData.mDepartment = departmentEt.getText().toString();

                mAdapter.add(0,addData);
                break;

            case R.id.del_btn :
                EditText delltmelndexEt = findViewById(R.id.del_item_index_edit);
                Integer index = Integer.parseInt(delltmelndexEt.getText().toString());
                mAdapter.delete(index);

                break;
            case R.id.all_del_btn :
                mAdapter.clear();
                break;
        }
    }
}

 

 일단 베이스 어댑터를 상속받아서 사용한다 . 그리고 메소드 오버라이딩을 통하여 사용하는데 노란색 두부분은 꼭작성을 해줘야 오류가 안난다 . 

 

그리고 getView에 보면 convertView를 보면 이건 최적화를 위한 것이다. 

최적화란 애초에 스크롤을 할때 보여지는 화면이 나오면 안보여지는 화면도 있을것이다. 그럴 떄 그 뷰를 재활용 한다고 생각하면 된다 . 말로는 힘드니 코드보면 이해 할거다 

 

어레이어댑터 

메인

public class MainActivity extends AppCompatActivity {

    ListView mListView = null;
    ArrayList<Student> mData = null;

    ArrayAdapterEx mAdapter = null;


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

        // 1. 어뎁터에서 사용할 데이터 설정
        // ====================================================================
        mData = new ArrayList<Student>();

        for (int i = 0; i < 100; i++) {
            Student student = new Student();

            student.mName = "슈퍼성근" + i;
            student.mNumber = "95000" + i;
            student.mDepartment = "컴퓨터 공학" + i;

            mData.add(student);
        }
        // ====================================================================

        // 2. 어뎁터를 생성하고 데이터 설정
        // ====================================================================
        mAdapter = new ArrayAdapterEx(this,
                R.layout.list_view_item_layout,
                R.id.name_text,
                mData);
        // ====================================================================

        // 3. 리스트뷰에 어뎁터 설정
        // ====================================================================
        mListView = (ListView) findViewById(R.id.list_view);
        mListView.setAdapter(mAdapter);
        // ====================================================================
    }

    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.add_btn: {
                EditText nameEt =
                        (EditText) findViewById(R.id.name_edit);
                EditText numberEt =
                        (EditText) findViewById(R.id.number_edit);
                EditText departmentEt =
                        (EditText) findViewById(R.id.department_edit);

                Student addData = new Student();

                addData.mName = nameEt.getText().toString();
                addData.mNumber = numberEt.getText().toString();
                addData.mDepartment = departmentEt.getText().toString();

                mAdapter.add(addData);

                break;
            }

            case R.id.del_btn: {
                EditText delItmeIndexEt =
                        (EditText) findViewById(R.id.del_item_index_edit);

                Integer index =
                        Integer.parseInt(delItmeIndexEt.getText().toString());

                mAdapter.remove(mData.get(index));
                break;
            }

            case R.id.all_del_btn: {
                mAdapter.clear();

                break;
            }

            case R.id.sort_btn: {
                mAdapter.sort(new Comparator<Student>() {
                    @Override
                    public int compare(Student lhs, Student rhs) {
                        Collator collator = Collator.getInstance();
                        return collator.compare(rhs.mName, lhs.mName);
                    }
                });

                break;
            }
        }
    }
}

 

어레이어댑터

public class ArrayAdapterEx extends ArrayAdapter<Student> {


    public ArrayAdapterEx(Context context,
                          int resource,
                          int textViewResourceId,
                          List<Student> objects) {
        super(context, resource, textViewResourceId, objects);
    }

    class ViewHolder {
        TextView mNameTv;
        TextView mNumberTv;
        TextView mDepartmentTv;
    }

    @Override
    public View getView(int position,
                        View convertView,
                        ViewGroup parent) {
        View itemLayout = super.getView(position, convertView, parent);

        ViewHolder viewHolder = (ViewHolder) itemLayout.getTag();

        if (viewHolder == null) {
            viewHolder = new ViewHolder();
            viewHolder.mNameTv =
                    (TextView) itemLayout.findViewById(R.id.name_text);
            viewHolder.mNumberTv =
                    (TextView) itemLayout.findViewById(R.id.number_text);
            viewHolder.mDepartmentTv =
                    (TextView) itemLayout.findViewById(R.id.department_text);

            itemLayout.setTag(viewHolder);
        }

        viewHolder.mNameTv.setText(getItem(position).mName);
        viewHolder.mNumberTv.setText(getItem(position).mNumber);
        viewHolder.mDepartmentTv.setText(getItem(position).mDepartment);

        return itemLayout;
    }
}

 

거의 비슷한걸 볼수 있는데 어레이는 sort하여 정렬한것도 볼 수 있다 . 

 

심플어댑터

단순히 보여주기위함 수정삭제 추가 등 안된다 .

public class MainActivity extends AppCompatActivity {

    ListView mListView = null;
    ArrayList<HashMap<String, String>> mData = null;

    SimpleAdapter mAdapter = null;


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

        // 1. 뷰와 그 뷰에 설정될 데이터를 연결하기 위한 배열을 정의한다.
        // ====================================================================
        String[] dataKeyList = {"name", "number", "department"}; // 키

        int[] viewIdList = {R.id.name_text,    // 뷰아이디 리스트 
                R.id.number_text,       
                R.id.department_text};
        // ====================================================================

        // 2. 어뎁터에서 사용할 데이터 설정
        // ====================================================================
        mData = new ArrayList<HashMap<String, String>>();

        for (int i = 0; i < 100; i++) {
            HashMap<String, String> mapData = new HashMap<String, String>();

            mapData.put(dataKeyList[0], "슈퍼성근" + i);
            mapData.put(dataKeyList[1], "95000" + i);
            mapData.put(dataKeyList[2], "컴퓨터 공학" + i);

            mData.add(mapData);
        }
        // ====================================================================

        // 3. 어뎁터를 생성하고 데이터 설정
        // ====================================================================
        mAdapter = new SimpleAdapter(this,  
                mData,    //데이터를 1
                R.layout.list_view_item_layout, //한패
                dataKeyList,    //1 
                viewIdList); //2 한패
        // ====================================================================

        // 4. 리스트뷰에 어뎁터 설정
        // ====================================================================
        mListView = (ListView) findViewById(R.id.list_view);
        mListView.setAdapter(mAdapter);
        // ====================================================================
    }

}

 

결과 화면 (베이스 어댑터 ) 

 

잘 실행 되는걸 볼 수있다. 

반응형