3

Я прочитал несколько вопросов о stackoverflow, рассматривающих эту проблему, но я не мог решить свою проблему. В recyclerview отображаются веб-просмотры. Моя проблема заключается в том, что адаптер, сначала загрузите правильные значения (рисунок ниже):Адаптер RecyclerView принимает неправильные значения во время прокрутки

right behavior

, но когда я прокручиваю вниз и выполните прокрутку до первой позиции снова, неправильные значения отображаются в WebView (ниже изображения):

right behavior

Я думаю, что эта проблема может возникать из ранее начатых нагрузок в 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); 

Мой вопрос >> ли вызов bindEbook(String pg) занимает больше времени по сравнению с прокруткой recyclerview или связан с Android архитектуры ??

+0

ваш viewholder неправильно –

+0

@ war_Hero: Можете ли вы дать мне более подробную информацию? –

+0

Опубликовать свой адаптер плохо объясните, ТОЛЬКО КАК ДЖИСТ ПРОСМОТР ВНУТРИ ВИДЕОМАРАТА ИСПОЛЬЗУЕТСЯ ДЛЯ ПОДДЕРЖАНИЯ ПОЗИЦИИ –

ответ

1

Пожалуйста, попробуйте несколько вещей:

1) поставил log после String pg = mPgs.get(position); и см., значение pg после этой строки;

В bindEbook():
2) положить log чтобы увидеть, какая pg значение вступает;
3) поставил mListWebView.clearHistory() или mListWebView.loadUrl("about:blank") перед тем mListWebView.loadDataWithBaseURL() просто чтобы увидеть это ваше webview действительно загружается новую страницу

Также - попробуйте заменить webview простой textView - вы увидите, проблема в webview или в adapter.

+0

Благодарим за полезный ответ. Я нахожу решение. Я удалил 'bindEbook (String pg)' и напрямую обновил webview в методе 'onBindViewHolder'. (1) и (2) являются ключевыми моментами для решения проблемы. (3) не влияло. Проблема в адаптере. Еще раз спасибо. –

0

У меня была очень похожая проблема, которую я решил после обширной отладки. Надеюсь, это вам поможет:

В моем проекте я показываю горизонтальный RecyclerView в вертикальном RecyclerView. Код можно увидеть here и here, и я объяснил, что я делаю на своем сайте here.

Я заметил, что при прокрутке внешнего (вертикального) RecyclerView значения внутреннего (горизонтального) RecyclerView, где перепутались. Это похоже на вашу проблему. Установите некоторые команды консольного журнала (Log.v) здесь и там в моем внутреннем адаптере RecyclerView (так называемый MeasurementsAdapter), один специально в классе владельца внутреннего вида, где привязаны данные: Открытый класс 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 «перерабатывал» некоторые случайные данные. Это не то, что я хотел, и мой результат был очень похож на вас.

Итак, после того, как я прочитал метод notifyDataSetChanged в документации RecyclerView. В адаптере моего внешнего RecyclerView (так называемый Stationsadapter) Я модифицировал метод связывания во внутреннем классе ViewHolder и выполнить adapter.notifyDataHasChanged метод там (см линии 84 в 1)

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(); 
    } 

Теперь мои RecyclerViews показывают правильные данные , Я очень надеюсь, что это поможет вам и другим.

Приветствия Бен

Смежные вопросы