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