我有一个具有多个视图类型的viewholder。
滚动时,只有当getItemViewType
更改值时,才会调用onBindViewHolder。这会导致我的列表项无法正确更新。
这是虫子吗?或者我做错了什么。从新的recyclerView
类来看,这似乎是非常奇怪的行为。
这是我的适配器:
package se.davison.smartrecycleradapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
/**
* Created by richard on 10/11/14.
*/
public class SectionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String TAG = SectionAdapter.class.getSimpleName();
private final LayoutInflater inflater;
private final int sectionLayoutId;
private SparseIntArray positionSection;
private LinkedHashMap<AdapterItem, List<AdapterItem>> items = new LinkedHashMap<AdapterItem, List<AdapterItem>>();
private List<Class<? extends AdapterItem>> itemTypes = new ArrayList<Class<? extends AdapterItem>>(20);
public SectionAdapter(Context context, int sectionLayoutId, LinkedHashMap<AdapterItem, List<AdapterItem>> items) {
this.inflater = LayoutInflater.from(context);
this.sectionLayoutId = sectionLayoutId;
this.items = items;
initList(items);
}
public SectionAdapter(Context context, int sectionLayoutId) {
this.inflater = LayoutInflater.from(context);
this.sectionLayoutId = sectionLayoutId;
this.items = new LinkedHashMap<AdapterItem, List<AdapterItem>>();
initList(items);
}
@Override
public int getItemViewType(int position) {
AdapterItem item = getItem(position);
Log.d(TAG, position + ": class " + item.getClass());
return itemTypes.indexOf(item.getClass());
}
@Override
public int getItemCount() {
int count = 0;
if (items == null) {
return 0;
}
for (AdapterItem key : items.keySet()) {
count++;
List<AdapterItem> childItems = items.get(key);
if (childItems != null) {
count += childItems.size();
}
}
return count;
}
private void initList(HashMap<AdapterItem, List<AdapterItem>> items) {
positionSection = new SparseIntArray(items.size());
int count = 0;
int sectionIndex = -1;
for (AdapterItem key : items.keySet()) {
Class headerClass = key.getClass();
if (!itemTypes.contains(headerClass)) {
itemTypes.add(headerClass);
}
List<AdapterItem> childItems = items.get(key);
sectionIndex = count;
if (childItems != null) {
for (AdapterItem item : childItems) {
Class clazz = item.getClass();
if (!itemTypes.contains(clazz)) {
itemTypes.add(clazz);
}
positionSection.put(count, sectionIndex);
count++;
}
}
count++;
}
setHasStableIds(true);
}
private AdapterItem getItem(int position) {
int totalChildCount = 0;
int separatorCount = 0;
for (AdapterItem key : items.keySet()) {
if (position == 0 || position == totalChildCount + separatorCount) {
return key;
}
separatorCount++;
List<AdapterItem> list = items.get(key);
int couldCount = countList(list);
if (position < totalChildCount + separatorCount + couldCount) {
return list.get(position - (totalChildCount + separatorCount));
}
totalChildCount += couldCount;
}
return null;
}
public void setItems(LinkedHashMap<AdapterItem, List<AdapterItem>> items) {
this.items = items;
notifyDataSetChanged();
}
public void setItemsAtHeader(int id, List<AdapterItem> items) {
AdapterItem header = null;
for (AdapterItem key : this.items.keySet()) {
if (key.headerId() == id) {
header = key;
break;
}
}
if (header == null) {
throw new IllegalArgumentException(String.format("No header with id %s is found", id));
}
setItemsAtHeader(header, items);
}
private void setItemsAtHeader(AdapterItem header, List<AdapterItem> items) {
this.items.put(header, items);
}
private int countList(List<?> list) {
return list == null ? 0 : list.size();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
AdapterItem firstItem = getFirstItemWithClass(itemTypes.get(viewType));
return firstItem.onCreateViewHolder(inflater, viewGroup);
}
private AdapterItem getFirstItemWithClass(Class<? extends AdapterItem> clazz) {
for (AdapterItem key : items.keySet()) {
if (key.getClass() == clazz) {
return key;
}
List<AdapterItem> childItems = items.get(key);
if (childItems != null) {
for (AdapterItem item : childItems) {
if (item.getClass() == clazz) {
return item;
}
}
}
}
throw new IllegalStateException("Something is wrong, you dont have any items with that class in your list");
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
AdapterItem item = getItem(position);
Log.d(TAG, "ITEM = " + item.getClass().getSimpleName());
Log.d(TAG, "POS = " + position);
if (item instanceof OneLineAdapterItem) {
Log.d(TAG, "TEXT = " + ((OneLineAdapterItem) item).getText());
}
item.onBindViewHolder(viewHolder, position);
}
}
我还提取了如下内容:
public abstract class AdapterItem<VH extends RecyclerView.ViewHolder> {
public boolean isHeader(){
return false;
}
public int headerId(){
return -1;
}
public abstract VH onCreateViewHolder(LayoutInflater inflater, ViewGroup parent);
public abstract void onBindViewHolder(VH viewHolder, int position);
}
对于部分
public class SectionAdapterItem extends AdapterItem<SectionAdapterItem.ViewHolder> {
private String text;
private boolean dividerVisible = false;
public static class ViewHolder extends RecyclerView.ViewHolder{
TextView titel;
ImageView divider;
public ViewHolder(View itemView) {
super(itemView);
titel = (TextView) itemView.findViewById(android.R.id.title);
divider = (ImageView) itemView.findViewById(android.R.id.icon);
}
}
public void setDividerVisible(boolean dividerVisible) {
this.dividerVisible = dividerVisible;
}
public boolean isDividerVisible() {
return dividerVisible;
}
@Override
public boolean isHeader() {
return true;
}
@Override
public int headerId() {
return super.headerId();
}
public SectionAdapterItem(String text) {
this.text = text;
}
@Override
public ViewHolder onCreateViewHolder(LayoutInflater inflater, ViewGroup parent) {
return new ViewHolder(inflater.inflate(R.layout.top_header, parent, false));
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.titel.setText(text);
viewHolder.divider.setVisibility(dividerVisible?View.VISIBLE:View.GONE);
}
}
它对第一个可见行运行良好,但随后失败。
当您设置setHasStableIds(true)
时,意味着如果我们请求一个位置的ID,任何特定项都将始终返回相同的ID,而不管它在列表中的位置如何。这使我们能够识别一个特定的项目,即使其位置发生变化,这将在以后很有用。
为此,您需要在适配器中实现mtgetItemId
方法,并返回其位置。
@Override
public long getItemId(int position) {
return position;
}
使用setHasStableIds(true)时,我忘记实现
getItemId
;
实现这一点解决了问题!
我正在使用Flask构建一个应用程序,该应用程序在Google App Engine SDK上本地运行。出于某种原因,我的入口点是<code>main。py,仅启动一次。 < code>main.py: < code>myapp/bootstrap.py: 返回MyApp.Application的实例 < code > myapp/application . py : 扩展 Flask,注册路由,
问题内容: 我在SQL Server中运行合并。在我的更新中,我只想更新值已更改的行。版本行在每次更新时都会递增。下面是一个示例: 现在,如果我只想更新行,从而增加版本,则仅在名称更改的情况下。 问题答案: 可以有。另外,无需更新。 如果Last_Name或First_Name可为空,则例如在比较trg.Last_Name <> src.Last_Name时,需要注意值。
问题内容: 我有一个,并且有一个侦听器连接到它。 现在,即使用户只是重新选择了先前选择的值,每次用户从下拉菜单中“选择”某项时,事件都会触发。 如果组合框的选定值与选定前的值不同,有什么方法可以仅触发事件? 我想我可以将组合框的值存储在不同的字段中,并在每次事件触发时将其进行比较,这似乎有点过头了。我有20个左右这样的组合框。我宁愿不要再有20个变量来存储值,这样事件就不会触发。 一定有更好的方法
问题内容: 我正在编写一个API解析Twitter机器人,对OOP来说是个新手。我有一些依赖于全局变量的现有Python代码,并认为我可以借此机会学习。 我有以下Team类,这些类在解析API时会更新,并且希望在类属性更改时能够调用完全不相关的(外部)方法。 对于现有实例,何时更改,我希望调用以下方法(伪代码): 两件事情 - 一旦检测到属性已更改,如何从班级内部调用? 我可以从任何地方访问对象的
问题内容: 我希望当我将一个元素(用css制成的盒子)悬停时,主体的颜色从一种颜色变为另一种颜色,例如白色变为红色。问题在于,应该仅使用CSS而不使用JavaScript来完成此操作。而且,如果必须使用javascript,则在鼠标移开时,颜色应更改回前一颜色。 - - - - - - - -编辑 - - - - - - - - 其实我正在尝试: 问题答案: 纯CSS实验: HTML CSS
问题内容: 仅在真正更改数据的情况下,才有可能使用“更新后”触发器。我知道“新旧”。但是使用它们时,我只能比较列。例如“ NEW.count <> OLD.count”。 但我想要类似的东西:如果“ NEW <> OLD”,则运行触发器 一个例子: 关键是,有一个更新,但是 什么都没有改变 。但是无论如何,触发器都在运行。恕我直言,应该有一个没有的方法。 我知道我可以使用 如果现在b <> OLD