android - 如何更新 RecyclerView 中某个项目的特定 TextView?
问题描述
当用户单击另一个项目时,我想更新我的 RecyclerView 中的先前 TextView 项目:
例如,如果用户单击“lemanju”TextView,它会将字体颜色更改为橙色,当用户单击“Lightning”TextView 时,lemanju 的字体颜色应该变回黑色,而 Lighning 的字体颜色必须变为橙色,因为您可以在下面看到。
闪电被选中(现在发生了什么 -> 没有将 lemanju 的字体颜色更新回黑色)
我在我的适配器类中尝试了以下代码来实现此结果:
// set previous item TextColor to black.
holder.itemView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.BaseColor_1));
holder.adapter.notifyItemChanged(previousSamplePosition);
// set actual item TextColor to orange.
holder.itemView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.PrimaryColor_1));
不幸的是,当我点击闪电时,我无法将 lemanju 的字体颜色改回黑色......
有谁知道如何使用 notifyItemChanged 更改特定的 TextView?或者还有其他方法可以实现吗?
我的适配器类中的 onCreateViewHolder 方法,您可以在下面看到:
/**
* Sets the contents of an item at a given position in the RecyclerView.
* Called by RecyclerView to display the data at a specificed position.
*
* @param holder The view holder for that position in the RecyclerView.
* @param samplePosition The position of the item in the RecyclerView.
* <p>
*/
@Override
public void onBindViewHolder(@NonNull SampleViewHolder holder, int samplePosition) {
if (sampleList != null) {
Sample currentSample = sampleListFiltered.getCurrentList().get(samplePosition);
// Add the data to the view holder.
holder.sampleView.setText(currentSample.getName());
holder.bind(currentSample);
if (sampleNameSearched != null) {
String sampleName = Normalizer.normalize(sampleListFiltered.getCurrentList().get(samplePosition).getName(), Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "").toLowerCase();
Pattern sampleQuery = Pattern.compile(sampleNameSearched);
Matcher sampleMatcher = sampleQuery.matcher(sampleName);
SpannableStringBuilder spanString = new SpannableStringBuilder(sampleListFiltered.getCurrentList().get(samplePosition).getName());
while (sampleMatcher.find()) {
spanString.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), sampleMatcher.start(), sampleMatcher.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
holder.sampleView.setText(spanString);
} else {
// This solved the problem
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.BaseColor_1));
}
}
Bundle sampleBundle = new Bundle();
holder.sampleView.setOnClickListener(view -> {
sampleBundle.putLong("Sample", sampleListFiltered.getCurrentList().get(samplePosition).getId());
SampleCollectorListNavigatorFragment.addScreenToStack(0);
SampleCollectorListNavigatorFragment.setLastSurveyIdAccessed(sampleListFiltered.getCurrentList().get(samplePosition).getSurveyId());
Navigation.findNavController(view).navigate(R.id.action_sampleCollectorListNavigator_to_sampleCollectorInspectSampleFragment, sampleBundle);
});
holder.sampleView.setOnLongClickListener(view -> {
sampleBundle.putLong("Sample", sampleListFiltered.getCurrentList().get(samplePosition).getId());
if (sampleID == 0) {
// Access the view of the previous screen
((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).setVisibility(View.VISIBLE);
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.PrimaryColor_1));
} else if (sampleID == sampleListFiltered.getCurrentList().get(samplePosition).getId()) {
if (((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).getVisibility() == View.VISIBLE) {
((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).setVisibility(View.GONE);
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.BaseColor_1));
} else {
((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).setVisibility(View.VISIBLE);
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.PrimaryColor_1));
}
} else if (sampleID != sampleListFiltered.getCurrentList().get(samplePosition).getId()) {
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.BaseColor_1));
notifyItemChanged(previousSamplePosition);
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.PrimaryColor_1));
((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).setVisibility(View.VISIBLE);
}
sampleID = sampleListFiltered.getCurrentList().get(samplePosition).getId();
previousSamplePosition = samplePosition;
return true;
});
}
}
更新 - >如何解决这个问题?
为了解决我的代码中的问题,我必须在我的搜索过滤器中将字符串更新回黑色:
// This solved the problem
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.BaseColor_1));
但是,如果您的结构与我的不同,或者您只想更新回收器中以前的 TextView 项,您可以使用这部分代码:
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.BaseColor_1));
notifyItemChanged(previousSamplePosition);
会做的notifyItemChanged(previousSamplePosition)
伎俩。
解决方案
这是一个基本示例,下面我也添加了您的代码
你的适配器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private String[] mDataset;
List<TextView> textViews = new ArrayList<>();
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView textView;
public MyViewHolder(TextView v) {
super(v);
textView = v.findViewById(R.id.textView);
}
}
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textView.setText(mDataset[position]);
views.add(holder.textView);
}
@Override
public int getItemCount() {
return mDataset.length;
}
public List<TextView> getTextViews(){
return textViews;
}
}
您的活动
public class MainActivity extends AppCompatActivity {
private Button changeColorButton;
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
changeColorButton = findViewById(R.id.button);
recyclerView = findViewById(R.id.recyclerView);
MyAdapter adapter = new MyAdapter(new String[]{"Hello", "world"});
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
changeColorButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
int length = adapter.getTextViews().size();
List<TextView> textViews = adapter.textViews;
for(int i=0; i<length; i++){
textViews.get(i).setTextColor(Color.parseColor("#bdbdbd"));
}
}
});
}
}
现在至于你的代码
public static class SampleViewHolder extends RecyclerView.ViewHolder {
private final TextView sampleView;
/**
* Creates a new custom view holder to hold the view to display in the RecyclerView.
*
* @param sampleListView The view in which to display the data.
* @param adapter The adapter that manages the the data and views for the RecyclerView.
*/
public SampleViewHolder(View sampleListView) {
super(sampleListView);
sampleView = sampleListView.findViewById(R.id.data_name);
}
}
/**
* Inflates an item view and returns a new view holder that contains it.
* Called when the RecyclerView needs a new view holder to represent an item.
*
* @param parent The view group that holds the item views.
* @param viewType Used to distinguish views, if more than one type of item view is used.
* @return a view holder.
*/
@NonNull
@Override
public SampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// Inflate an item view.
View sampleListView = inflater.inflate(R.layout.fragment_sample_collector_list_sample, parent, false);
return new SampleViewHolder(sampleListView);
}
/**
* Sets the contents of an item at a given position in the RecyclerView.
* Called by RecyclerView to display the data at a specificed position.
*
* @param holder The view holder for that position in the RecyclerView.
* @param samplePosition The position of the item in the RecyclerView.
* <p>
* TODO: Most important method used
*/
@Override
public void onBindViewHolder(@NonNull SampleViewHolder holder, int samplePosition) {
if (sampleList != null) {
// Retrieve the data for that position.
//Sample currentSample = sampleListFiltered.get(samplePosition);
Sample currentSample = sampleListFiltered.getCurrentList().get(samplePosition);
// Add the data to the view holder.
holder.sampleView.setText(currentSample.getName());
holder.bind(currentSample);
list.add(holder.sampleView);
if (sampleNameSearched != null) {
String sampleName = Normalizer.normalize(sampleListFiltered.getCurrentList().get(samplePosition).getName(), Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "").toLowerCase();
Pattern sampleQuery = Pattern.compile(sampleNameSearched);
Matcher sampleMatcher = sampleQuery.matcher(sampleName);
SpannableStringBuilder spanString = new SpannableStringBuilder(sampleListFiltered.getCurrentList().get(samplePosition).getName());
while (sampleMatcher.find()) {
spanString.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), sampleMatcher.start(), sampleMatcher.end(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
holder.sampleView.setText(spanString);
}
}
Bundle sampleBundle = new Bundle();
holder.sampleView.setOnClickListener(view -> {
sampleBundle.putLong("Sample", sampleListFiltered.getCurrentList().get(samplePosition).getId());
SampleCollectorListNavigatorFragment.addPreviousScreen(0);
SampleCollectorListNavigatorFragment.setLastSurveyIdAccessed(sampleListFiltered.getCurrentList().get(samplePosition).getSurveyId());
Navigation.findNavController(view).navigate(R.id.action_sampleCollectorListNavigator_to_sampleCollectorInspectSampleFragment, sampleBundle);
});
holder.sampleView.setOnLongClickListener(view -> {
sampleBundle.putLong("Sample", sampleListFiltered.getCurrentList().get(samplePosition).getId());
// TODO: if the same button is clicked close the buttonPanel, else keep it open.
if (sampleID == 0) {
// Access the view of the previous screen
((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).setVisibility(View.VISIBLE);
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.PrimaryColor_1));
} else if (sampleID == sampleListFiltered.getCurrentList().get(samplePosition).getId()) {
if (((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).getVisibility() == View.VISIBLE) {
((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).setVisibility(View.GONE);
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.BaseColor_1));
} else {
((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).setVisibility(View.VISIBLE);
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.PrimaryColor_1));
}
} else if (sampleID != sampleListFiltered.getCurrentList().get(samplePosition).getId()) {
Toast.makeText(inflater.getContext(), "list size() " + list.size(), Toast.LENGTH_SHORT).show();
// I CANNOT CHANGE THE COLOR OF THE PREVIOUS SAMPLE RIGHT HERE.
List<RecyclerView.ViewHolder> vh = getItem();
changeColor(vh,previousSamplePosition);
holder.adapter.notifyItemChanged(previousSamplePosition);
holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.PrimaryColor_1));
((Activity) inflater.getContext()).findViewById(R.id.ButtonPanel).setVisibility(View.VISIBLE);
}
sampleID = sampleListFiltered.getCurrentList().get(samplePosition).getId();
previousSamplePosition = samplePosition;
return true;
});
}
public List<RecyclerView.ViewHolder> getItem(){
return list;
}
public void changeColor(List<RecyclerView.ViewHolder> vh, int previousSamplePosition) {
for (int i = 0; i < list.size(); i++) {
if(i == previousSamplePosition) {
// Does not change the previous TextView.
Toast.makeText(inflater.getContext(), "i -> " + i + " previousSamplePos -> " + previousSamplePosition, Toast.LENGTH_SHORT).show();
// How can I use the vh here?
//vh.get(i).setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.BaseColor_1));
//holder.adapter.notifyItemChanged(i);
}
}
}
}
让我知道它是否有效
推荐阅读
- c# - 如何识别在 c# 中生成的表行上是否应用了分页符?
- android - 为什么arcore示例可以从位于不同apk安装位置的arcore apk加载.so
- javascript - 如何从动态级联下拉列表中保存结果?
- c++ - 筛选检测和计算得到不同大小的关键点和描述符,这是怎么回事?
- javascript - 将几个结构怪异的物体合二为一
- excel - 比较不带空格的 SUMIF 中的字符串
- c# - 我可以覆盖引用(nuget)中的方法吗?
- python - 这可以通过一个简单的方程式来完成而不是循环来完成吗?
- javascript - 将 attr() 方法与内部具有函数的 each() 方法相结合的方法
- ios - 如何在 JWPlayer 播放列表中播放自定义索引?