【问题标题】:Recyclerview empty on first loadRecyclerview 首次加载时为空
【发布时间】:2022-07-04 16:22:31
【问题描述】:

嗨,就像标题中所说的那样,我试图让我的 recyclerview 工作,但它在第一次加载时总是显示为空。只有当我改变活动并回来时它才会出现。数据是在创建时获取的,但似乎没有传递给适配器。 所以我的问题是:如何在第一次加载时在 recyclerview 中加载数据?

RecyclerViewFragment.java

    private static final String TAG = "RecyclerViewFragment";
    private static final String KEY_LAYOUT_MANAGER = "layoutManager";
    private static final int SPAN_COUNT = 2;
    private static final int DATASET_COUNT = 60;
    public static ArrayList<String> arraylist_News = new ArrayList<String>();
    public static ArrayList<String> arraylist_Thumbs = new ArrayList<String>();
    public static ArrayList<String> arraylist_Links = new ArrayList<String>();
    private static String URL = "https://mangascan.cc/";
    public String titre;
    public String name;
    public String img;
    public String lien;

    private enum LayoutManagerType {
        GRID_LAYOUT_MANAGER,
        LINEAR_LAYOUT_MANAGER
    }

    protected LayoutManagerType mCurrentLayoutManagerType;

    protected RadioButton mLinearLayoutRadioButton;
    protected RadioButton mGridLayoutRadioButton;

    protected RecyclerView mRecyclerView;
    protected CustomAdapter mAdapter;
    protected RecyclerView.LayoutManager mLayoutManager;
    protected String[] mDataset;
    protected String[] mDatasetName;
    protected String[] mDatasetImg;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Initialize dataset, this data would usually come from a local content provider or
        // remote server.
        initDataset();
       new getWebsite().execute();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.recycler_view_frag, container, false);
        rootView.setTag(TAG);
        // BEGIN_INCLUDE(initializeRecyclerView)
        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
       //mRecyclerView.setHasFixedSize(false);
        // LinearLayoutManager is used here, this will layout the elements in a similar fashion
        // to the way ListView would layout elements. The RecyclerView.LayoutManager defines how
        // elements are laid out.
        mLayoutManager = new LinearLayoutManager(getActivity());
        mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;
        if (savedInstanceState != null) {
            // Restore saved layout manager type.
            mCurrentLayoutManagerType = (LayoutManagerType) savedInstanceState
                    .getSerializable(KEY_LAYOUT_MANAGER);
        }
        setRecyclerViewLayoutManager(mCurrentLayoutManagerType);

        // END_INCLUDE(initializeRecyclerView)
//        getParentFragmentManager().beginTransaction().detach(this).attach(this).commit();
        mAdapter = new CustomAdapter(getActivity(),mDataset,mDatasetName,mDatasetImg);
        // Set CustomAdapter as the adapter for RecyclerView.
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.ResetValues(mDataset);
//        mAdapter.notifyItemRangeChanged(0, arraylist_News.size());
        return rootView;
    }

    /**
     * Set RecyclerView's LayoutManager to the one given.
     *
     * @param layoutManagerType Type of layout manager to switch to.
     */
    public void setRecyclerViewLayoutManager(LayoutManagerType layoutManagerType) {
        int scrollPosition = 0;

        // If a layout manager has already been set, get current scroll position.
        if (mRecyclerView.getLayoutManager() != null) {
            scrollPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager())
                    .findFirstCompletelyVisibleItemPosition();
        }
                mLayoutManager = new LinearLayoutManager(getActivity(),RecyclerView.HORIZONTAL, false);
                mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;

        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.scrollToPosition(scrollPosition);
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        // Save currently selected layout manager.
        savedInstanceState.putSerializable(KEY_LAYOUT_MANAGER, mCurrentLayoutManagerType);
        super.onSaveInstanceState(savedInstanceState);
    }

    /**
     * Generates Strings for RecyclerView's adapter. This data would usually come
     * from a local content provider or remote server.
     */
    private void initDataset() {
        mDataset = new String[arraylist_News.size()];
        for (int i = 0; i < arraylist_News.size(); i++) {
            mDataset[i] = String.valueOf(arraylist_News.get(i));
        }
        mDatasetName = new String[arraylist_Links.size()];
        for (int i = 0; i < arraylist_Links.size(); i++) {
            mDatasetName[i] = String.valueOf(arraylist_Links.get(i));
        }
        mDatasetImg = new String[arraylist_Thumbs.size()];
        for (int i = 0; i < arraylist_Thumbs.size(); i++) {
            mDatasetImg[i] = String.valueOf(arraylist_Thumbs.get(i));
        }
    }

    private class getWebsite extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            arraylist_News.clear();
            arraylist_Thumbs.clear();
            arraylist_Links.clear();
        }

        private static final String userAgent = "Mozilla/5.0 (jsoup)";
        @Override
        protected Void doInBackground(Void... voids) {
            try {
                Document doc = Jsoup.connect(URL).userAgent(userAgent).timeout(12000).get();

                //scan-mangas get news script
                Element news = doc.select(".hot-thumbnails").first();
//                Log.d("jSoup", news.toString());
                for (Element e : news.select(".span3")){
                    titre = e.select("p").text().toString();
                    //Log.d("okk", titre);
                    img = e.select("img").attr("src");
                    lien = e.select("a").attr("href");
                    name = e.getElementsByClass("label label-warning").text().toString();
                    arraylist_News.add((titre));
                    arraylist_Thumbs.add(img);
                    arraylist_Links.add(name);
                }
                for (String str_Agil : arraylist_Thumbs)   // using foreach
                {
                    Log.e("NEWS:: " , str_Agil);
                }


        } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // This code will always run on the UI thread, therefore is safe to modify UI elements.
                    ((CustomAdapter)mRecyclerView.getAdapter()).ResetValues(mDataset);
                    mAdapter.notifyDataSetChanged();
                    mAdapter.notifyItemRangeInserted(0, arraylist_News.size());
                   //System.out.println("update ui");
                    mRecyclerView.removeAllViews();
                }
            });
        }
    }

CustomAdapter.java

private String[] mDataSet;
private String[] mDataSetName;
private String[] mDataSetImg;
Context context;

// BEGIN_INCLUDE(recyclerViewSampleViewHolder)
/**
 * Provide a reference to the type of views that you are using (custom ViewHolder)
 */
public static class ViewHolder extends RecyclerView.ViewHolder {
    private final TextView textView;
    private final TextView textView2;
    private final ImageView imgView;

    public ViewHolder(View v) {
        super(v);
        // Define click listener for the ViewHolder's View.
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "Element " + getAdapterPosition() + " clicked.");
            }
        });
        textView = (TextView) v.findViewById(R.id.textView);
        textView2 = (TextView) v.findViewById(R.id.textView2);
        imgView = (ImageView) v.findViewById(R.id.thumbnail);
    }
    public TextView getTextView() {
        return textView;
    }
    public TextView getTextView2() {
        return textView2;
    }
}
// END_INCLUDE(recyclerViewSampleViewHolder)

/**
 * Initialize the dataset of the Adapter.
 *
 * @param dataSet String[] containing the data to populate views to be used by RecyclerView.
 */
public CustomAdapter(Context context, String[] dataSet, String[] dataSet1, String[] dataSet2) {
    mDataSet = dataSet;
    mDataSetName = dataSet1;
    mDataSetImg = dataSet2;
    this.context = context;
}

// BEGIN_INCLUDE(recyclerViewOnCreateViewHolder)
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    // Create a new view.
    View v = LayoutInflater.from(viewGroup.getContext())
            .inflate(R.layout.text_row_item, viewGroup, false);

    return new ViewHolder(v);
}
// END_INCLUDE(recyclerViewOnCreateViewHolder)

// BEGIN_INCLUDE(recyclerViewOnBindViewHolder)
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
    Log.d(TAG, mDataSet[position] + " set.");

    // Get element from your dataset at this position and replace the contents of the view
    // with that element
    viewHolder.getTextView().setText(mDataSet[position]);
    viewHolder.getTextView2().setText(mDataSetName[position]);
    Picasso.with(viewHolder.imgView.getContext()).load(mDataSetImg[position]).into(viewHolder.imgView);

}
// END_INCLUDE(recyclerViewOnBindViewHolder)

// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
    return mDataSet.length;
}

public void ResetValues(String[] dataSet)
{
    notifyDataSetChanged();
}

感谢各位开发者

这是完整的项目,您可以对其进行测试:https://drive.google.com/file/d/15rx7vELGiwlIfxZH3Np6Joycrsf4PxO_/view?usp=sharing

我为此苦苦挣扎了三个月,请帮忙

【问题讨论】:

  • 发布完整代码..
  • 我做错了
  • “initDataset();”中的问题因为 ArrayLists 是空的,所以 mDataset 等 .. 在第一次加载时也会为空
  • 我试图反转这条线和new getWebsite().execute();,现在它什么也没有显示。你能告诉我@Dreamer 发生了什么
  • 我检查了它并且能够让它显示图像

标签: java android android-recyclerview


【解决方案1】:

此解决方案基于 Google drive 中的代码

转到 PageViewFragment.java 并更改它

 getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // This code will always run on the UI thread, therefore is safe to modify UI elements.

                if(pageAdapter==null){
                    pageAdapter =new PageAdapter(getActivity(), mDataset);
                    mRecyclerView.setAdapter(pageAdapter);
                } else {
                    pageAdapter.notifyDataSetChanged();
                    Log.d("dataset", "changed");

                }
            }
        });

到这里

   getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // This code will always run on the UI thread, therefore is safe to modify UI elements.
                    initDataset();
                    pageAdapter = new PageAdapter(getActivity(), mDataset);
                    mRecyclerView.setAdapter(pageAdapter);
                }
            });

【讨论】:

    猜你喜欢
    • 2018-04-06
    • 2017-05-16
    • 2018-05-18
    • 2019-03-25
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多