【问题标题】:recyclerview add data to the top without mess up scroll?recyclerview 将数据添加到顶部而不会弄乱滚动?
【发布时间】:2017-08-12 11:15:08
【问题描述】:

我正在尝试在回收站视图的滚动顶部添加一些日期。 这是工作,除了滚动,当添加一些新数据时它会搞砸一切。

我看到了这个话题:

Link 1

Link 2

但他们都没有解决我的问题。

也许有人可以帮我解决这个问题...

我使用 volley 获取一些数据,如下所示:

try {
                //Getting json
                json = array.getJSONObject(i);

                //Adding data to the object
                PostObj.setImageUrl(json.getString(Config.TAG_PPIC));
                ...


            } catch (JSONException e) {
                e.printStackTrace();
            }
            //Adding object to the list
            listLf.add(0, PostObj); //0, postobj
        }

        //Notifying the adapter that data has been added or changed
        //adapter.notifyDataSetChanged(); the scroll will jump to position 0
        adapter.notifyItemRangeChanged(0, adapter.getItemCount()); // still not working
    }

我尝试添加adapter.notifyItemRangeChanged(0, adapter.getItemCount());,但还是一样。

我也试过了:

// Save state
private Parcelable recyclerViewState;
recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();

// Restore state
recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);

它也不起作用。也许我把它放在错误的地方或什么的......

我想要一些建议我做错了什么以及如何获取新数据,通知适配器而不弄乱滚动位置?


编辑---------------------------------- 全班:

public class Comments extends BaseActivity {


    private List<LfGetSet> listLf;

    //Creating Views
    private RecyclerView recyclerView;
    private RecyclerView.LayoutManager layoutManager;
    private RecyclerView.Adapter adapter;

    //Volley Request Queue
    private RequestQueue requestQueue;
    private String requestCount = "0";
    private String lastrequestCount = "0";

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

        ViewGroup content = (ViewGroup) findViewById(R.id.content_frame);
        getLayoutInflater().inflate(R.layout.activity_comments, content, true);

        //Initializing Views
        recyclerView = (RecyclerView) findViewById(R.id.recyclerViewLf);
        recyclerView.setHasFixedSize(true);
        //layoutManager = new LinearLayoutManager(this);

        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setStackFromEnd(true);

        recyclerView.setLayoutManager(layoutManager);

        //Initializing our list
        listLf = new ArrayList<>();
        requestQueue = Volley.newRequestQueue(this);

        //Calling method to get data to fetch data
        getData();

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (isLastItemDisplaying(recyclerView)) {
                    getData();
                }
            }
        });

        //initializing our adapter
        adapter = new LfAdapter(listLf, this);

        //Adding adapter to recyclerview
        recyclerView.setAdapter(adapter);


    }

    private JsonArrayRequest getDataFromServer(String requestCount) {
        ...
        return jsonArrayRequest;
    }

    //This method will get data from the web api
    private void getData() {
        //Adding the method to the queue by calling the method getDataFromServer
        requestQueue.add(getDataFromServer(requestCount));
        lastrequestCount = requestCount;
        //Incrementing the request counter
        requestCount++;
    }

    //This method will parse json data
    private void parseData(JSONArray array) {
        for (int i = 0; i < array.length(); i++) {
            //Creating the object
            LfGetSet PostObj = new LfGetSet();
            JSONObject json = null;
            try {
                //Getting json
                json = array.getJSONObject(i);

                //Adding data to the object
                PostObj.setImageUrl(json.getString(Config.TAG_PPIC));
                ...


            } catch (JSONException e) {
                e.printStackTrace();
            }
            //Adding object to the list
            listLf.add(0, PostObj); //0, postobj
        }

        //Notifying the adapter that data has been added or changed
        adapter.notifyDataSetChanged();
    }

    //This method would check that the recyclerview scroll has reached the bottom or not
    private boolean isLastItemDisplaying(RecyclerView recyclerView) {
        if (recyclerView.getAdapter().getItemCount() != 0) {
            int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
            if (lastVisibleItemPosition != RecyclerView.NO_POSITION
                    && lastVisibleItemPosition == 1
                    && lastrequestCount != requestCount
                    && requestCount != "0")
                return true;
        }
        return false;
    }

}

【问题讨论】:

  • 添加项目时应使用notifyItemInserted 方法。
  • 我试过 adapter.notifyItemInserted(0);adapter.notifyItemInserted(adapter.getItemCount()) ,但它们都不起作用。他们似乎将所有帖子分组在第一个位置,并在再次滚动底部和顶部时显示它们......我做错了什么吗? @RobCo

标签: android android-studio android-recyclerview


【解决方案1】:

您可以尝试这种方法,按照正常方式将新项目添加到列表中,然后更新数组中的数据并将新项目放在顶部。

   // Add a new item the usual way so it goes at the bottom

    int x = 0;

   // Create a new Data list. New item goes 1st

   // Create a Loop

    myList.remove(x); // Remove item from the array at position

    MyList myList = new MyList();

    myList.add(x, theData); // Add data to array at position


    // Now that new data has been inserted to the Array at position X update the List item at that same Position. I usually do this in the Background.

    Handler handler = new Handler();

    final int finalX = x;
    final Runnable r = new Runnable() {
        public void run() {
            adapter.notifyItemChanged(finalX);  // Notify Adapter that the Items data has changed and Update
        }
    };

    handler.post(r);

    x++;

从数据库中读取更新数据然后使用新数据动态更新列表项的代码。但在您的情况下,您需要添加 1 个新项目并使用数组和列表中位置 0 处的新项目数据更新列表。旧项目的位置偏移 1。

public void updateStocks() {

        System.out.println("Updating");
        int rec = db.getRecordsCount() - 1;

        List<Records> record = db.getAllRecords();

        int x = 0;

        for (Records cn : record) {

            stocksList.remove(x);

            Livestocks stocks = new Livestocks();

            stocks.setID(cn.getID());
            stocks.setName(cn.getName());
            stocks.setTicker(cn.getTicker());
            stocks.setPrice(cn.getPrice());
            stocks.setOpen(cn.getOpen());
            stocks.setChange(cn.getChange());
            stocks.setPchange(cn.getPchange());
            stocks.setDhigh(cn.getDhigh());
            stocks.setDlow(cn.getDlow());
            stocks.setYhigh(cn.getYhigh());
            stocks.setYlow(cn.getYlow());
            stocks.setVol(cn.getVol());
            stocks.setShares(cn.getShares());
            stocks.setIown(cn.getIown());
            stocks.setMcap(cn.getMcap());
            stocks.setStatus(cn.getStatus());
            stocks.setExchange(cn.getExchange());

            stocksList.add(x, stocks);

            Handler handler = new Handler();

            final int finalX = x;
            final Runnable r = new Runnable() {
                public void run() {
                    adapter.notifyItemChanged(finalX);
                }
            };

            handler.post(r);

            x++;

            if (rec == x) {
            //do nothing
            }
        }

    }

【讨论】:

  • 我会试试你的解决方案,谢谢! finalX 是我要插入的数据数不是吗?第 i 个数字是多少?
  • @Gabriela Dias -- 不能将 x 的值复制到最终整数,因此可以在处理程序中读取它以更新列表项的数据,因为您在屏幕上的相同位置看到它作为数组数据 -- 数组数据和列表项从零开始具有相同的位置 -- x 和 finalX 具有相同的值
  • @Gabriela Dias -- 为了进一步解释,我提供的代码步骤通常用于即时更新列表项,而无需刷新整个列表。但是,因为您要添加 1 并希望它位于顶部,所以您需要以通常的方式添加 1,以便总数组项与列表项不匹配,最后您即时更新,但您放置了新的第 1 个。您可能会注意到 1 项数据略有变化
  • 哦,我明白了!我会试试你的解决方案。它很聪明。谢谢!
  • @Gabriela Dias——它会工作的。添加 1 个新项目后,通常您所做的就是将旧数据移动到列表中的 + 1 位置,并在您要求新项目成为列表中的第一个时动态更新。我将添加用于我使用的股票应用程序的代码,但它所做的只是从数据库中读取更新的数据并即时更新列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多