在NotifyDataSetChanged()之后RecyclerView不会更新,打开和关闭屏幕后内容会显示

弗朗西斯科·M。

我刚接触Android,正在与一群大学的朋友建立和应用。我们遇到的问题是,当通过从服务器获取数据来填充要显示的元素列表时,数据会加载并添加到列表中,但是recyclerView从不显示它(即使从我的自定义Adapter调用NotifyDataSetChanged之后)。回到我们使用硬编码数据测试应用程序时,这从未发生。

奇怪的是,关闭显示然后重新打开后,元素列表会显示在recyclerView上(当我重新打开屏幕时,将调用自定义适配器的onBindViewHolder)。此外,如果我替换片段包含一个带有另一个的recyclerView,然后返回到它,数据被加载到列表中,但未显示。

我想知道的是为什么会发生这种情况,我该怎么做才能解决(通过解决这个问题,我的意思是在启动片段时向recyclerView填充正确的项目,并在向其中添加更多元素时更新recyclerView清单)

我们正在使用自定义adpater和Retrofit从服务器获取数据。

这是代码

包含recyclerView的片段

    public class EventViewListFragment extends Fragment implements EventListAdapter.ClickListener{

    private RestClient restClient;
    private Builder builder;
    private String token ;

    private boolean userScrolled = true;
    int pastVisiblesItems, visibleItemCount, totalItemCount;

    private LinearLayoutManager mLayoutManager;

    private RecyclerView recyclerView;
    private EventListAdapter eventListAdapter;

    private Button btnNewEvent;

    FloatingActionButton suggestFAB;

    private int currentPage=1;


    public  EventViewListFragment(){
        restClient = new RestClient();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        System.out.println("Se llamo al onCreate de EventViewListFragment");
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        System.out.println("se llamo al onCreateView de EvENT List Fragment");
        // Inflate the layout for this fragment
        View layout =inflater.inflate(R.layout.fragment_events_list, container, false);
        setUpElements(layout);
        addListeners();
        return layout;
    }

    private void setUpElements(View layout)
    {
        recyclerView = (RecyclerView) layout.findViewById(R.id.eventList);
        eventListAdapter = new EventListAdapter(getActivity());
        eventListAdapter.setClickListener(this);
        eventListAdapter.setData(getInitialData());
        recyclerView.setAdapter(eventListAdapter);
        mLayoutManager=new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(mLayoutManager);
        suggestFAB = (FloatingActionButton)  layout.findViewById(R.id.suggestFAB);
        builder = new Builder();
    }

    private void addListeners()
    {
        addNewEventListener();
        addScrollBottomListener();
    }



    private void addNewEventListener()
    {
        /*btnNewEvent.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view)
            {
                EventsActivity.getInstance().toNewEventForm();
            }
        });*/

        suggestFAB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                EventsActivity.getInstance().toNewEventForm();
                currentPage=1;
            }
        });
    }

    public List<Event> getInitialData()
    {
        List<Event> data=new ArrayList<>();
        data = getEvents(data);
        return data;
    }

    @Override
    public void itemClicked(View view, int position) {
        EventsActivity.getInstance().toEventPage(eventListAdapter.getItemAtPos(position));
        currentPage=1;

    }
    private void addScrollBottomListener() {
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

                super.onScrollStateChanged(recyclerView, newState);
                if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                    userScrolled = true;

                }

            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx,
                                   int dy) {

                super.onScrolled(recyclerView, dx, dy);
                // Here get the child count, item count and visibleitems
                // from layout manager

                visibleItemCount = mLayoutManager.getChildCount();
                totalItemCount = mLayoutManager.getItemCount();
                pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
                if (userScrolled && (visibleItemCount + pastVisiblesItems) == totalItemCount) {
                    userScrolled = false;

                    addNewElementsToList();
                }

            }

        });

    }

    private void addNewElementsToList()
    {
        Toast.makeText(getActivity(), "Cargando Mas Elementos", Toast.LENGTH_SHORT).show();
        eventListAdapter.setData(getEvents(eventListAdapter.getData()));
    }

    private List<Event> getEvents(final List<Event> eventsList)
    {
        System.out.println("Asignando CALL");
        Call<JsonElement> eventPage = restClient.getConsumerService().getEvents(token, "", currentPage, 10);
        System.out.println("Enquequeing");
        eventPage.enqueue(new Callback<JsonElement>() {
            @Override
            public void onResponse(Response<JsonElement> response) {
                JsonObject responseBody = response.body().getAsJsonObject();
                if (responseBody.has("events")) {
                    JsonArray jsonArray = responseBody.getAsJsonArray("events");
                    System.out.println(jsonArray.size());
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JsonObject storedObject = jsonArray.get(i).getAsJsonObject();
                        Event current = new Event();
                        current.setEventId(storedObject.get("id").getAsInt());
                        current.setName(storedObject.get("title").getAsString());
                        Calendar startCal = new GregorianCalendar();
                        startCal.setTimeInMillis((storedObject.get("starts_at").getAsLong()) * 1000);
                        current.setStartDateTime(startCal);
                        Calendar endCal = new GregorianCalendar();
                        endCal.setTimeInMillis((storedObject.get("ends_at").getAsLong()) * 1000);
                        current.setFinishDateTime(endCal);
                        current.setImgUrl(storedObject.get("image").getAsString());
                        eventsList.add(current);
                    }
                } else {
                    if (responseBody.has("error")) {
                        System.out.println("ERROR");
                        wan.wanmarcos.models.Error error = builder.buildError(responseBody.get("error").getAsJsonObject());
                        Toast.makeText(getActivity(), "Error : " + error.toString(), Toast.LENGTH_SHORT).show();
                    } else {

                    }
                }
            }

            @Override
            public void onFailure(Throwable t) {
            }
        });
        eventListAdapter.notifyDataSetChanged();
        currentPage++;
        return eventsList;
    }
}

RecyclerView的自定义适配器

    public class EventListAdapter extends  RecyclerView.Adapter<EventListAdapter.EventListViewHolder>{
    private LayoutInflater inflater;
    private List<Event> data = Collections.emptyList();
    private Context context;
    private ClickListener clickListener;

    public EventListAdapter(Context context){
        inflater = LayoutInflater.from(context);
        this.context=context;
    }

    @Override
    public EventListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view =  inflater.inflate(R.layout.event_list_item, parent, false);
        EventListViewHolder holder = new EventListViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(EventListViewHolder holder, int position) {
        System.out.println("se llamo al onBindViewHolder de ELA");
        Event current = getData().get(position);
        holder.title.setText(current.getName());
        Picasso.with(context)
                .load(current.getImgUrl())
                .into(holder.img);
        String startDateAndTime = current.CalendarToString(current.getStartDateTime())+" - "+current.CalendarToString(current.getFinishDateTime());
        holder.dateAndTime.setText(startDateAndTime);
    }

    public void setClickListener(ClickListener clickListener){

        this.clickListener=clickListener;
    }

    @Override
    public int getItemCount() {

        return getData().size();
    }

    public List<Event> getData() {
        return data;
    }

    public void setData(List<Event> data) {
        this.data = data;
    }

    class EventListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView title;
        TextView dateAndTime;
        ImageView img;

        public EventListViewHolder(View itemView) {

            super(itemView);
            itemView.setOnClickListener(this);
            title = (TextView) itemView.findViewById(R.id.eventListTitle);
            img = (ImageView) itemView.findViewById(R.id.eventListImage);
            dateAndTime =(TextView) itemView.findViewById(R.id.eventListDateAndTime);
        }


        @Override
        public void onClick(View v) {

            if(clickListener!=null)
            {
                clickListener.itemClicked(v,getPosition());
            }
        }

    }

    public Event getItemAtPos(int pos)
    {
        return getData().get(pos);
    }


    public interface ClickListener{
        public void itemClicked(View view,int position);
    }



}

Fragment XML File

    <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="wan.wanmarcos.fragments.EventViewListFragment">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/eventList"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scrollbars="vertical"
                >
            </android.support.v7.widget.RecyclerView>
    </RelativeLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/suggestFAB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        app:layout_anchorGravity="bottom|right|end"
        android:layout_margin="16dp"
        android:clickable="true"
        android:src="@mipmap/ic_add_white_48dp" />

</android.support.design.widget.CoordinatorLayout>
黑带

eventsList在你Activitydata你的适配器是两个不同的集合。您正在填充前者,但没有填充后者。Intializedatanew ArrayList<>替代Collections.emptyList();,然后在适配器中添加了一个方法,调用中的addAll,这样的:

public void addAll(final List<Event> new events) {
      final int currentCount = data.size();
      synchronized(data) {
         data.addAll(events);
      }
      if (Looper.getMainLooper() == Looper.myLooper()) {
          notifyItemRangeInserted(currentCount, events.size());
      } else {
          new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                notifyItemRangeInserted(currentCount, events.size());
            }
          });
      }
}

if else检查您是从ui线程还是从其他线程调用addAll,并notifyItemRangeInserted以安全的方式调用调用Activitywhen时onResponse,完全填满后eventsList,只需调用eventListAdapter.addAll(eventsList)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

RecyclerView仅在旋转屏幕后显示

在打开/关闭软键盘之前,RecyclerView不会更新

在adapter.notifyDataSetChanged() 之后Listview 不会更新

旋转屏幕后,Recyclerview不会调整大小

notifyDataSetChanged方法不会更新RecyclerView布局

再次打开屏幕后,MapView完全显示

如何打开和关闭屏幕?

OpenGL程序仅显示屏幕后面的内容

打开新屏幕后返回到屏幕时,LiveData值会重新出现

锁定屏幕后,如何防止屏幕关闭?

更新屏幕后不再锁定

使用 Reactjs 和 WebRTC 选择屏幕后屏幕共享屏幕不显示

jQuery .append()内容不会显示在屏幕上

DrawerLayout旋转屏幕后不关闭

使用启动器关闭GIMP之后重新打开GIMP时,不会出现“图层和工具箱”窗口

打开/关闭内容和锚链接

关闭外接显示器的笔记本电脑屏幕后的最低屏幕分辨率

如何在 iOS 设备中解锁屏幕后立即激活和打开我的应用程序

Swiftui 显示和关闭入职屏幕

Webbrowser不会显示txt文件的更新版本,但是打开新的浏览器会显示正确的文件

在“安全更新”到4.15.0-24-通用#26-Ubuntu屏幕之后,显示日志内容未登录

单击按钮时显示导航栏 - 之后不会关闭

ListView不会显示更改,直到notifyDataSetChanged之后焦点发生更改为止

无线按钮显示反复打开和关闭

连接外部屏幕后,如何自动关闭内部屏幕?

关闭屏幕后,减慢android应用的自动关闭过程

CSS Marquee动画-在完全关闭屏幕之前再次显示内容

单击显示内容和悬停更新内容

显示带有打开/关闭文本的隐藏多个内容