RecyclerView 适配器在滚动期间采用错误的值
RecyclerView adapter taking wrong values during scrolling
我已经阅读了几个关于 Whosebug 的问题来解决这个问题,但我无法解决我的问题。 recyclerview 显示网络视图。我的问题是适配器最初加载正确的值(下图):
但是当我向下滚动并再次向上滚动到第一个位置时,webview 中显示了错误的值(下图):
我认为这个问题可能源于之前开始加载到 webview,但我不知道如何处理这种行为。这是我的代码的相关部分:
/* in my notation, pg is equivalent to page.*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_ebook_list, container, false);
mEbookRecyclerView = (RecyclerView) view.findViewById(R.id.ebook_recycler_view);
mLayoutManager = new LinearLayoutManager(getActivity());
mEbookRecyclerView.setLayoutManager(mLayoutManager);
updateUI();
return view;
}
@Override
public void onResume() {
super.onResume();
updateUI();
}
private void updateUI() {
if (mAdapter == null) {
EbookLab ebookLab = EbookLab.get(getActivity());
List<String> pgs = ebookLab.getPgs();
mAdapter = new EbookAdapter(pgs);
mEbookRecyclerView.setAdapter(mAdapter);
}
}
/* ******codes for preparation of menus which I have ignored *******/
private class EbookHolder extends RecyclerView.ViewHolder {
private String mPg;
public EbookHolder(LayoutInflater inflater, ViewGroup container) {
super(inflater.inflate(R.layout.list_item_ebook, container, false));
mListWebView = (WebView) itemView.findViewById(R.id.list_web_View);
mListWebView.getSettings().setLoadWithOverviewMode(true);
}
public void bindEbook(String pg) {
mPg = pg;
mListWebView.loadDataWithBaseURL("file:///android_asset/", "Stack Over Flow " + String.valueOf(glbPos), "text/html", "UTF-8", null);
}
}
private class EbookAdapter extends RecyclerView.Adapter<EbookHolder> {
private List<String> mPgs;
public EbookAdapter(List<String> pgs) {
mPgs = pgs;
}
@Override
public EbookHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
return new EbookHolder(layoutInflater, parent);
}
@Override
public void onBindViewHolder(EbookHolder holder, int position) {
String pg = mPgs.get(position);
glbPos = position;//A global variable for position
holder.bindEbook(pg);
}
@Override
public int getItemCount() {
return mPgs.size();
}
public void setPgs(List<String> pgs) {
mPgs.clear();
mPgs.addAll(pgs);
notifyDataSetChanged();
}
}
感谢任何帮助。
更新:在我的代码中,我将 mListWebView 定义为全局变量。但是应该定义在private class EbookHolder extends RecyclerView.ViewHolder
里面。
然后我删除了 bindEbook(String pg)
方法并直接更新了 mListWevView
里面 public void onBindViewHolder(EbookHolder holder, int position)
:
holder.mListWebView.loadDataWithBaseURL("file:///android_asset/", "Stack Over Flow " + String.valueOf(glbPos), "text/html", "UTF-8", null);
我的问题>>与滚动recyclerview相比,调用bindEbook(String pg)
是否需要更长的时间,或者它与Android架构有关??
请尝试一些事情:
1)把log
放在String pg = mPgs.get(position)
之后;看看那行之后是哪个 pg
值;
在 bindEbook()
:
2) 放log
看传入的是哪个pg
值;
3) 将 mListWebView.clearHistory()
或 mListWebView.loadUrl("about:blank")
放在 mListWebView.loadDataWithBaseURL()
之前只是为了看看您的 webview
是否真的在加载新页面
另外 - 尝试用简单的 textView
替换 webview
- 你会看到,问题出在 webview
或 adapter
.
我有一个非常相似的问题,经过大量调试后我解决了。希望对您有所帮助:
在我的项目中,我在垂直 RecyclerView 中显示水平 RecyclerView。代码可见here and here and I explained what I do on my website here.
我注意到当向下滚动外部(垂直)RecyclerView 时,内部(水平)RecyclerView 的值出现混乱。这类似于你的问题。在我的内部 RecyclerView 适配器(称为 MeasurementsAdapter)中在这里和那里设置一些控制台日志命令(Log.v),其中一个专门在内部视图持有者 class 中,其中绑定了数据:
public class MeasurementsViewHolder 扩展 RecyclerView.ViewHolder {
[此处省略代码]
public MeasurementsViewHolder (View itemView) {
super(itemView);
[code omitted here]
}
public void bindMeasurement (String name, double value, String unit, int color) {
mNameView.setText(name);
mValueView.setText(String.valueOf(Math.round(value)));
mUnitsView.setText(unit);
mBoxLayout.setBackgroundColor(color);
// Log.v(TAG, name + " " + value); <-- here I was logging
}
我观察到当我在某个点滚动时,这个 "bindMeasurement" 方法不再执行。
我猜 RecyclerView 是 "recycling" 一些随机数据。这不是我想要的,我的结果和你的很像。
所以,在我阅读 RecyclerView 文档中的 notifyDataSetChanged-method 之后。在我外部 RecyclerView 的适配器(称为 Stationsadapter)中,我修改了内部 ViewHolder class 中的绑定方法并在那里执行 adapter.notifyDataHasChanged 方法(参见 1 中的第 84 行)
public class StationsViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {public TextView mStationInfoView;
private MeasurementsAdapter mMeasurementsAdapter;
/**
* Constructor of inner class StationsViewHolder
* @param itemView
*/
public StationsViewHolder(View itemView) {
super(itemView);
[code omitted here]
}
/**
* Bind weather station to view
* @param station is a class containing data of one weather station
*/
public void bindStation (Station station) {
[code omitted here]
mMeasurementsAdapter.notifyDataSetChanged();
}
现在我的 RecyclerView 显示正确的数据。我非常希望这对您和其他人有所帮助。
干杯
本
我已经阅读了几个关于 Whosebug 的问题来解决这个问题,但我无法解决我的问题。 recyclerview 显示网络视图。我的问题是适配器最初加载正确的值(下图):
但是当我向下滚动并再次向上滚动到第一个位置时,webview 中显示了错误的值(下图):
我认为这个问题可能源于之前开始加载到 webview,但我不知道如何处理这种行为。这是我的代码的相关部分:
/* in my notation, pg is equivalent to page.*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_ebook_list, container, false);
mEbookRecyclerView = (RecyclerView) view.findViewById(R.id.ebook_recycler_view);
mLayoutManager = new LinearLayoutManager(getActivity());
mEbookRecyclerView.setLayoutManager(mLayoutManager);
updateUI();
return view;
}
@Override
public void onResume() {
super.onResume();
updateUI();
}
private void updateUI() {
if (mAdapter == null) {
EbookLab ebookLab = EbookLab.get(getActivity());
List<String> pgs = ebookLab.getPgs();
mAdapter = new EbookAdapter(pgs);
mEbookRecyclerView.setAdapter(mAdapter);
}
}
/* ******codes for preparation of menus which I have ignored *******/
private class EbookHolder extends RecyclerView.ViewHolder {
private String mPg;
public EbookHolder(LayoutInflater inflater, ViewGroup container) {
super(inflater.inflate(R.layout.list_item_ebook, container, false));
mListWebView = (WebView) itemView.findViewById(R.id.list_web_View);
mListWebView.getSettings().setLoadWithOverviewMode(true);
}
public void bindEbook(String pg) {
mPg = pg;
mListWebView.loadDataWithBaseURL("file:///android_asset/", "Stack Over Flow " + String.valueOf(glbPos), "text/html", "UTF-8", null);
}
}
private class EbookAdapter extends RecyclerView.Adapter<EbookHolder> {
private List<String> mPgs;
public EbookAdapter(List<String> pgs) {
mPgs = pgs;
}
@Override
public EbookHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
return new EbookHolder(layoutInflater, parent);
}
@Override
public void onBindViewHolder(EbookHolder holder, int position) {
String pg = mPgs.get(position);
glbPos = position;//A global variable for position
holder.bindEbook(pg);
}
@Override
public int getItemCount() {
return mPgs.size();
}
public void setPgs(List<String> pgs) {
mPgs.clear();
mPgs.addAll(pgs);
notifyDataSetChanged();
}
}
感谢任何帮助。
更新:在我的代码中,我将 mListWebView 定义为全局变量。但是应该定义在private class EbookHolder extends RecyclerView.ViewHolder
里面。
然后我删除了 bindEbook(String pg)
方法并直接更新了 mListWevView
里面 public void onBindViewHolder(EbookHolder holder, int position)
:
holder.mListWebView.loadDataWithBaseURL("file:///android_asset/", "Stack Over Flow " + String.valueOf(glbPos), "text/html", "UTF-8", null);
我的问题>>与滚动recyclerview相比,调用bindEbook(String pg)
是否需要更长的时间,或者它与Android架构有关??
请尝试一些事情:
1)把log
放在String pg = mPgs.get(position)
之后;看看那行之后是哪个 pg
值;
在 bindEbook()
:
2) 放log
看传入的是哪个pg
值;
3) 将 mListWebView.clearHistory()
或 mListWebView.loadUrl("about:blank")
放在 mListWebView.loadDataWithBaseURL()
之前只是为了看看您的 webview
是否真的在加载新页面
另外 - 尝试用简单的 textView
替换 webview
- 你会看到,问题出在 webview
或 adapter
.
我有一个非常相似的问题,经过大量调试后我解决了。希望对您有所帮助:
在我的项目中,我在垂直 RecyclerView 中显示水平 RecyclerView。代码可见here and here and I explained what I do on my website here.
我注意到当向下滚动外部(垂直)RecyclerView 时,内部(水平)RecyclerView 的值出现混乱。这类似于你的问题。在我的内部 RecyclerView 适配器(称为 MeasurementsAdapter)中在这里和那里设置一些控制台日志命令(Log.v),其中一个专门在内部视图持有者 class 中,其中绑定了数据: public class MeasurementsViewHolder 扩展 RecyclerView.ViewHolder { [此处省略代码]
public MeasurementsViewHolder (View itemView) {
super(itemView);
[code omitted here]
}
public void bindMeasurement (String name, double value, String unit, int color) {
mNameView.setText(name);
mValueView.setText(String.valueOf(Math.round(value)));
mUnitsView.setText(unit);
mBoxLayout.setBackgroundColor(color);
// Log.v(TAG, name + " " + value); <-- here I was logging
}
我观察到当我在某个点滚动时,这个 "bindMeasurement" 方法不再执行。
我猜 RecyclerView 是 "recycling" 一些随机数据。这不是我想要的,我的结果和你的很像。
所以,在我阅读 RecyclerView 文档中的 notifyDataSetChanged-method 之后。在我外部 RecyclerView 的适配器(称为 Stationsadapter)中,我修改了内部 ViewHolder class 中的绑定方法并在那里执行 adapter.notifyDataHasChanged 方法(参见 1 中的第 84 行)
public class StationsViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {public TextView mStationInfoView;
private MeasurementsAdapter mMeasurementsAdapter;
/**
* Constructor of inner class StationsViewHolder
* @param itemView
*/
public StationsViewHolder(View itemView) {
super(itemView);
[code omitted here]
}
/**
* Bind weather station to view
* @param station is a class containing data of one weather station
*/
public void bindStation (Station station) {
[code omitted here]
mMeasurementsAdapter.notifyDataSetChanged();
}
现在我的 RecyclerView 显示正确的数据。我非常希望这对您和其他人有所帮助。
干杯 本