728x90

RecyclerviewAdapter 에서 Interface로 Activity 로 값을 넘기는 방법에 대한 코드와 Checkbox 에서 전체 선택/해제를 위해 별도의 RelativeLayout 으로 전체선택, 취소, 전송 등의 버튼을 처리하도록 한다.

구현은 전체를 다 구현한 것이 아니라 핵심사항만 구현했지만, 이 정도로도 좋은 코드라고 본다.


MainActivity.java

public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.OnItemClickListener {
    private final String TAG = this.getClass().getSimpleName();
    Context context;

    public ArrayList<Address_Item> addressItemList = new ArrayList<>(); // 서버 원본 데이터 리스트
    private RecyclerView mRecyclerView;
    private RecyclerViewAdapter mAdapter;
    private SearchView editsearch;

    RemoteService remoteService;

    public static RelativeLayout relative2;
    public static boolean isCheckFlag = false;
    public CheckBox checkAll;

    private BackPressHandler backPressHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = MainActivity.this;
        backPressHandler = new BackPressHandler(this);

        initView();
    }

    private void initView() {
        createAddressList(); // 서버 데이터 가져오기
        buildRecyclerView();
        setButtons();
    }

    private void setButtons(){
        isCheckFlag = false;
        // Relative layout 정의
        relative2 = findViewById(R.id.list_view_relative2);

        if (isCheckFlag == false) {
            relative2.setVisibility(View.GONE);
        } else if (isCheckFlag == true) {
            relative2.setVisibility(View.VISIBLE);
        }

        // all checkbox
        checkAll = findViewById(R.id.lv_checkbox_all);
        checkAll.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (checkAll.isChecked() == true) {
                mAdapter.selectAll();
                mAdapter.notifyDataSetChanged();
            } else {
                mAdapter.unselectall();
                mAdapter.notifyDataSetChanged();
            }
        });

        Button cancel = findViewById(R.id.btn_cancel);
        cancel.setOnClickListener(v -> {
            isCheckFlag = false;
            relative2.setVisibility(View.GONE);
            mAdapter.unselectall();
            checkAll.setChecked(false); // 전체 선택 체크박스 해제
            mAdapter.notifyDataSetChanged();
        });

        Button send = findViewById(R.id.btn_send);
        final String[] listview_items = {"그룹문자 보내기", "연락처 저장"};
        final AlertDialog.Builder items_builder = new AlertDialog.Builder(MainActivity.this);
        items_builder.setTitle("해당 작업을 선택하세요");
        items_builder.setItems(listview_items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case 0:
                        Toast.makeText(getApplicationContext(), "그룹문자 보내기 구현하세요.", Toast.LENGTH_SHORT).show();
                        break;
                    case 1:
                        Toast.makeText(getApplicationContext(), "연락처 저장을 구현하세요.", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });
        items_builder.create();

        send.setOnClickListener(v ->

                items_builder.show());

    }

    private void buildRecyclerView(){
        mRecyclerView = findViewById(R.id.address_listview);
        mRecyclerView.setHasFixedSize(true);
        LinearLayoutManager manager = new LinearLayoutManager(context);
        mAdapter = new RecyclerViewAdapter(context,addressItemList);

        DividerItemDecoration decoration = new DividerItemDecoration(context,manager.getOrientation());
        mRecyclerView.addItemDecoration(decoration);
        mRecyclerView.setLayoutManager(manager);
        mRecyclerView.setAdapter(mAdapter);

        mAdapter.setOnItemSelectClickListener(this);
    }

    private void createAddressList() {
         // 서버 데이터 가져오기 구현 메서드는 https://link2me.tistory.com/1850 참조
    }

    @Override
    public void onBackPressed() {
        backPressHandler.onBackPressed();
    }

    @Override
    public void onItemClicked(View view, Address_Item item, int position) {
        Toast.makeText(context, "position : "+position + " clieck item name : "+item.getUserNM(), Toast.LENGTH_SHORT).show();
    }
}


RecyclerViewAdapter.java

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
    private final String TAG = this.getClass().getSimpleName();
    Context context;
    private List<Address_Item> rvItemList;

    // 인터페이스 선언 -------------------------------------------------------------
    private OnItemClickListener mListener;

    public interface OnItemClickListener {
        void onItemClicked(View view, Address_Item item, int position);
    }

    public void setOnItemSelectClickListener(OnItemClickListener listener){
        mListener = listener;
    }
    // 인터페이스 ----------------------------------------------------------------

    public class ViewHolder extends RecyclerView.ViewHolder{
        LinearLayout child_layout;
        ImageView photo_Image;
        TextView tv_name;
        TextView tv_mobileNO;
        TextView tv_officeNO;
        ImageView call_btn;
        CheckBox cbSelect;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            child_layout = itemView.findViewById(R.id.child_layout);
            photo_Image = itemView.findViewById(R.id.profile_Image);
            tv_name = itemView.findViewById(R.id.child_name);
            tv_mobileNO = itemView.findViewById(R.id.child_mobileNO);
            tv_officeNO = itemView.findViewById(R.id.child_officeNO);
            call_btn = itemView.findViewById(R.id.call_btn);
            cbSelect = itemView.findViewById(R.id.listcell_checkbox);
        }
    }

    public RecyclerViewAdapter(Context context, List<Address_Item> itemList) {
        this.context = context;
        rvItemList = itemList;
    }

    public void selectAll(){ // checkbox 전체 선택
        for(int i=0;i < rvItemList.size();i++){
            rvItemList.get(i).setCheckBoxState(true);
        }
        notifyDataSetChanged();
    }
    public void unselectall(){ // checkbox 전체 해제
        for(int i=0;i < rvItemList.size();i++){
            rvItemList.get(i).setCheckBoxState(false);
        }
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.address_item,parent,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Log.d(TAG,"onBindViewHolder: called."); // 실제로 데이터를 표시하는 부분
        Address_Item currentItem = rvItemList.get(position);

        String photoURL = Value.IPADDRESS + "photos/" + currentItem.getPhoto();
        if(photoURL.contains("null")){
            Glide.with(context).asBitmap().load(R.drawable.photo_base).into(holder.photo_Image);
        } else {
            Glide.with(context).asBitmap().load(photoURL).into(holder.photo_Image);
        }
        holder.tv_name.setText(currentItem.getUserNM());
        holder.tv_mobileNO.setText(PhoneNumberUtils.formatNumber(currentItem.getMobileNO()));
        holder.tv_officeNO.setText(PhoneNumberUtils.formatNumber(currentItem.getTelNO()));

        holder.photo_Image.setOnClickListener(view1 -> {
            if(mListener != null){
                mListener.onItemClicked(view1,currentItem,position);
            }
        });

        holder.call_btn.setOnClickListener(view -> {
            Toast.makeText(context, "전화걸기 또는 문자 보내기를 할 수 있어요.", Toast.LENGTH_SHORT).show();
        });

        if (isCheckFlag == false) {
            holder.call_btn.setVisibility(View.VISIBLE);
            holder.call_btn.setOnClickListener(view -> builder.show());
            holder.cbSelect.setVisibility(View.GONE);
            holder.child_layout.setOnClickListener(view ->
                    Toast.makeText(context, "상세보기를 눌렀습니다 ===" + currentItem.getUid(), Toast.LENGTH_SHORT).show());

            holder.child_layout.setOnLongClickListener(v -> {
                isCheckFlag = true;
                relative2.setVisibility(View.VISIBLE);
                notifyDataSetChanged();
                return true;
            });
        } else {
            holder.call_btn.setVisibility(View.GONE);
            holder.cbSelect.setVisibility(View.VISIBLE);
            holder.cbSelect.setTag(position); // This line is important.

            // 체크 박스 클릭하면 CheckBoxState 에 반영한다. setOnCheckedChangeListener 대신 사용
            holder.cbSelect.setOnClickListener(v -> {
                if(rvItemList.get(position).getCheckBoxState() == true){
                    rvItemList.get(position).setCheckBoxState(false);
                } else {
                    rvItemList.get(position).setCheckBoxState(true);
                }
            });

            holder.child_layout.setOnClickListener(v -> {
                if(holder.cbSelect.isChecked() == false){
                    holder.cbSelect.setChecked(true);
                    rvItemList.get(position).setCheckBoxState(true);
                } else {
                    holder.cbSelect.setChecked(false);
                    rvItemList.get(position).setCheckBoxState(false);
                }
            });
        }

        // 재사용 문제 해결
        if(rvItemList.get(position).getCheckBoxState() == true){
            holder.cbSelect.setChecked(true);          
        } else {
            holder.cbSelect.setChecked(false);          
        }

    }

    @Override
    public int getItemCount() {
        return rvItemList.size();
    }

}


Address_Item.kt

import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@Parcelize
data class Address_Item (
    // 결과를 받을 모델 (ArrayList 에 저장하므로 val 로 선언하면 안된다)
    var uid: String="",
    var userNM: String="",
    var mobileNO: String?=null,
    var telNO: String?=null,
    var photo: String?=null,
    var checkBoxState: Boolean
): Parcelable


address_item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="1dp"
    app:cardCornerRadius="1dp">

    <LinearLayout
        android:id="@+id/child_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp">

        <ImageView
            android:id="@+id/profile_Image"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:src="@mipmap/ic_launcher" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_weight="4"
            android:orientation="vertical">

            <TextView
                android:id="@+id/child_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingBottom="2dip"
                android:text="이름"
                android:textSize="20sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/child_mobileNO"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="left"
                android:text="휴대폰번호"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/child_officeNO"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="left"
                android:text="사무실번호"
                android:textStyle="bold" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginLeft="5dp"
            android:layout_weight="1"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/call_btn"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:layout_gravity="center"
                android:gravity="center_horizontal|center_vertical"
                android:src="@drawable/btn_phone" />

        </LinearLayout>

        <CheckBox
            android:id="@+id/listcell_checkbox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:focusable="false" />

    </LinearLayout>
</androidx.cardview.widget.CardView>



728x90
블로그 이미지

Link2Me

,