如何在主要活动中使用按钮 onclicklistener 进行回收视图项目
Posted
技术标签:
【中文标题】如何在主要活动中使用按钮 onclicklistener 进行回收视图项目【英文标题】:How to use button onclicklistener for recycleview item inside main activity 【发布时间】:2019-07-25 00:41:03 【问题描述】:我在使用 android 应用程序时遇到了这个问题:我有一个 recycleview
,每个项目都有一个删除按钮。我知道我可以在适配器的onBindViewHolder
内添加每个行项目的按钮onclicklistener
,但我希望它专门用于 MainActivity 内部,而不是适配器。这是我的 recycleview 的简要草图:
sketch
这是我的适配器的代码:
public class EntryAdapter extends RecyclerView.Adapter<EntryAdapter.MyViewHolder>
private Context context;
private CRUD db;
private List<Entry> entryList;
public class MyViewHolder extends RecyclerView.ViewHolder
ImageView type;
ImageView person;
TextView amount;
TextView amount_ron;
ImageButton deleteB, editB, payB;
TextView description;
TextView timestamp;
TextView positionTxt, noHolderPositionTxt;
LinearLayout containter;
Typeface SR, SB, SL;
MyViewHolder(View view)
super(view);
this.SB = Typeface.createFromAsset(context.getAssets(), "fonts/sansation_bold.ttf");
this.SR = Typeface.createFromAsset(context.getAssets(), "fonts/sansation_regular.ttf");
this.SL = Typeface.createFromAsset(context.getAssets(), "fonts/sansation_light.ttf");
containter = view.findViewById(R.id.item_container);
type = view.findViewById(R.id.debt_type);
person = view.findViewById(R.id.debt_person);
amount = view.findViewById(R.id.entry_cost);
amount.setTypeface(SR);
amount_ron = view.findViewById(R.id.entry_cost_ron);
amount_ron.setTypeface(SR);
deleteB = view.findViewById(R.id.delete_button);
editB = view.findViewById(R.id.edit_button);
payB = view.findViewById(R.id.pay_button);
description = view.findViewById(R.id.descriptionTxt);
description.setTypeface(SL);
timestamp = view.findViewById(R.id.timestamp);
timestamp.setTypeface(SR);
positionTxt = view.findViewById(R.id.position);
noHolderPositionTxt = view.findViewById(R.id.positionnotwithholder);
db = new CRUD(context);
public EntryAdapter(Context context, List<Entry> entryList)
this.context = context;
this.entryList = entryList;
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_entry, parent, false);
return new MyViewHolder(itemView);
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position)
Entry entry = entryList.get(holder.getAdapterPosition());
holder.positionTxt.setText(String.valueOf(holder.getAdapterPosition()));
holder.noHolderPositionTxt.setText(String.valueOf(position));
switch(entry.getType())
case "FOOD": holder.type.setImageResource(R.drawable.food);
break;
case "FLOWERS": holder.type.setImageResource(R.drawable.flowers);
break;
case "GROCERIES": holder.type.setImageResource(R.drawable.groceries);
break;
case "HOLIDAY": holder.type.setImageResource(R.drawable.holiday);
break;
case "PHARMACY": holder.type.setImageResource(R.drawable.pharmacy);
break;
case "BILLS": holder.type.setImageResource(R.drawable.bills);
break;
case "CLOTHES": holder.type.setImageResource(R.drawable.clothes);
break;
case "TRANSPORT": holder.type.setImageResource(R.drawable.transport);
break;
case "ITEMS": holder.type.setImageResource(R.drawable.items);
break;
case "OTHERS": holder.type.setImageResource(R.drawable.others);
break;
switch (entry.getPerson())
case "ew": holder.person.setImageResource(R.drawable.crisu_to_radu_small);
break;
case "wr": holder.person.setImageResource(R.drawable.radu_to_crisu_big);
break;
switch (entry.getIsPaid())
case "YES": holder.containter.setAlpha((float) 0.3);
holder.payB.setVisibility(View.GONE);
holder.deleteB.setVisibility(View.GONE);
holder.editB.setVisibility(View.GONE);
break;
case "NO": holder.containter.setAlpha((float) 1);
holder.payB.setVisibility(View.VISIBLE);
holder.deleteB.setVisibility(View.VISIBLE);
holder.editB.setVisibility(View.VISIBLE);
break;
holder.amount.setText(entry.getAmount());
holder.description.setText(entry.getDescription());
holder.timestamp.setText(formatDate(entry.getTimestamp()));
// deleteEntry(holder.getAdapterPosition());
@Override
public int getItemCount()
return entryList.size();
private void deleteEntry(int position)
db.deleteEntry(entryList.get(position));
entryList.remove(position);
notifyItemRemoved(position);
notifyDataSetChanged();
notifyItemRangeChanged(position, entryList.size());
private String formatDate(String dateStr)
try
@SuppressLint("SimpleDateFormat") SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = fmt.parse(dateStr);
@SuppressLint("SimpleDateFormat") SimpleDateFormat fmtOut = new SimpleDateFormat("MMM d, HH:mm");
return fmtOut.format(date);
catch (ParseException ignored)
return "";
这是我的 MainActivity:
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fonts();
recyclerView = findViewById(R.id.recycler_view);
no_entry_message = findViewById(R.id.no_entry_message);
no_entry_message.setTypeface(SL);
title = findViewById(R.id.finance_title);
title.setTypeface(SB);
subtitle = findViewById(R.id.finance_subtitle);
subtitle.setTypeface(SL);
card_title = findViewById(R.id.total_title);
card_title.setTypeface(SR);
money_amount = findViewById(R.id.total_money);
money_amount.setTypeface(SB);
money_rom = findViewById(R.id.total_ron);
money_rom.setTypeface(SB);
total_calculation = findViewById(R.id.total_button);
total_calculation.setTypeface(SR);
total_container = findViewById(R.id.total_card_container);
db = new CRUD(this);
entryList.addAll(db.getAllEntries());
fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
isUpdateDilog = false;
addEntryDialog(null, -1);
);
mAdapter = new EntryAdapter(this, entryList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
emptyList();
// private void deleteEntry(int position)
//
// db.deleteEntry(entryList.get(position));
// entryList.remove(position);
// mAdapter.notifyItemRemoved(position);
// emptyList();
//
所以基本上,每次我点击 recyclerview 项目内的删除按钮时,我都希望在 MainActivity 中发生 onclick 事件并使用方法 deleteEntry(position) 以便我可以从本地 sqlite 数据库中删除特定项目。
另外,如果我想在我的适配器的 onBindViewHolder 中添加一个条件,我该如何更改(例如)来自 MainActivity 的 textview 的颜色?
更新 - H.sanati 的回答
再次感谢您的回答,H.sanati。这是我所做的全部更改:
创建了这个界面:
public interface OnClickListener
void onClick(int position, String button_pressed);
整数位置将我的项目位置存储在列表中,字符串将告诉我按下了 3 个按钮中的哪一个。
然后在我的Recyclview Adapter中:
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_entry, parent, false);
final MyViewHolder holder = new MyViewHolder(itemView);
holder.deleteB.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
((MainActivity)context).onClick(holder.getAdapterPosition(), "DELETE_B");
);
holder.editB.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
((MainActivity)context).onClick(holder.getAdapterPosition(), "EDIT_B");
);
holder.payB.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
((MainActivity)context).onClick(holder.getAdapterPosition(), "PAY_B");
);
return holder;
请注意,deleteB、editB 和 payB 都是出现在每个列表项中的按钮。上面界面中的字符串告诉你按下了哪一个。
然后在我的MainActivity中:
public class MainActivity extends AppCompatActivity implements OnClickListener
@Override
public void onClick(int item_position, String which_button_was_pressed)
switch (which_button_was_pressed)
case "DELETE_B":
deleteEntry(item_position);
Toast.makeText(this, "Delete button at position:" + item_position + "was pressed", Toast.LENGTH_SHORT).show();
break;
case "EDIT_B":
Toast.makeText(this, "Edit button at position:" + item_position + "was pressed", Toast.LENGTH_SHORT).show();
break;
case "PAY_B":
Toast.makeText(this, "Pay button at position:" + item_position + "was pressed", Toast.LENGTH_SHORT).show();
break;
这里有一个 Toast 按摩,以确认按下了正确的按钮,接下来,我将为每种情况添加我的方法。另外我建议在 MainActivity 的方法中(比如说 delete 方法,您可以查看它),您应该添加以下标有 @@@ 的行,以获得准确的列表大小和位置更新:
private void deleteEntry(int position)
db.deleteEntry(entryList.get(position));
entryList.remove(position);
@@@ mAdapter.notifyItemRemoved(position);
@@@ mAdapter.notifyDataSetChanged();
@@@ mAdapter.notifyItemRangeChanged(position, entryList.size());
emptyList();
希望这会有所帮助。谢谢!
【问题讨论】:
RecyclerView onClick的可能重复 【参考方案1】:首先,创建一个接口:
public interface OnClickListener
void onClick();
然后在你的活动中实现这个接口:
class MainActivity extends AppCompatActivity implements OnClickListener
@Override
public void onClick()
//code
在 onClick 方法中做任何你想做的事,然后在你的 recyclerview 中调用它:
((MainActivity)context).onClick();
最好在onCreateViewHolder
中设置您的听众,以便在 recyclerview 中平滑滚动,如下所示:
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View view = LayoutInflater.from(context).inflate(R.layout.item_entry, parent, false);
MyViewHolder holder = new MyViewHolder(view);
holder.itemView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
((MainActivity)context).onClick();
);
return holder;
【讨论】:
非常感谢,我对接口和回收视图有点陌生,这很有帮助! 很高兴它对您有所帮助。 @RFM以上是关于如何在主要活动中使用按钮 onclicklistener 进行回收视图项目的主要内容,如果未能解决你的问题,请参考以下文章