【问题标题】:RecyclerView items disappear after switching between fragmentsRecyclerView项目在fragment之间切换后消失
【发布时间】:2016-07-10 06:34:01
【问题描述】:

我的应用中有 4 个片段,它们在 NavActivity 中进行管理:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_nav);
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);


    fab = (FloatingActionButton) findViewById(R.id.fab);


    // Fab for fragments
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }
        @Override
        public void onPageSelected(int position) {
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            switch (state) {
                case ViewPager.SCROLL_STATE_DRAGGING:
                case ViewPager.SCROLL_STATE_SETTLING:
                    fab.hide(); // Hide animation
                    break;
                case ViewPager.SCROLL_STATE_IDLE:
                    switch (viewPager.getCurrentItem()) {
                        case 0:
                            fragment1.shareFab(fab); 
                        case 1:
                            fragment2.shareFab(fab); 
                            fab.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    startActivity(new Intent(NavActivity.this, MapsActivity.class));
                                }
                            });
                            break;
                        default:
                            fragment1.shareFab(null);
                            break;
                    }
                    if(viewPager.getCurrentItem() == 0 || viewPager.getCurrentItem() == 1)
                        fab.show(); // Show animation
                    break;
            }

        }
    });

    tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());

        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
    tabLayout.setupWithViewPager(viewPager);
}

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new MainFragment(), "Main");
    adapter.addFragment(new AboutFragment(), "About");
    adapter.addFragment(new CartFragment(), "Cart");
    adapter.addFragment(new CatalogFragment(), "Catalog");
    viewPager.setAdapter(adapter);
}


///////////new class
class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    if (fragments != null) {
        for (Fragment fragment : fragments) {
            fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

}

我面临一个问题,在片段之间切换后项目消失了我认为 RecyclerView 的实现和 viewHolder 与它有关。

我正在尝试使用 volley 从我的服务器获取数据,进入片段 C(片段编号 3),数据流很好,一切都正确显示。

如果我换成碎片 B(frag num 2) 或 D(frag num 4),仍然一切正常。 但是,如果不正确交换到 frag A(frag num 1) 并返回到 frag 3(我的列表项在哪里), 一切都消失了,我得到空白屏幕,即使我上下交换仍然不会再次下载项目。

这是带有我的 RecyclerView 的 Frag num 3:

private FloatingActionButton mSharedFab;
private List<MyProducts> productsList;

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

//Volley Request Queue
private RequestQueue requestQueue;


private int requestCount = 1;
private static final String URL_INDEX = "http://myserverip/android/product.php?page=";
//Tag values to read from json
public static final String TAG_IMAGE_URL = "product_img";
public static final String TAG_PRODUCT_SN = "product_serial_num";
public static final String TAG_PRODUCT_TITLE = "product_title";
public static final String TAG_PRODUCT_PRICE = "product_price";
public static final String TAG_PRODUCT_DESCRIPTION = "product_description";


public CartFragment() {
    // Required empty public constructor
}

 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_cart, container, false);
    recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
    layoutManager = new LinearLayoutManager(getActivity().getApplicationContext(), LinearLayoutManager.VERTICAL, false);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setHasFixedSize(true);

    //Initializing our superheroes list
    productsList = new ArrayList<>();
    requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());

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

    //Adding an scroll change listener to recyclerview
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP)
    {
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
        {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (isLastItemDisplaying(recyclerView)) {
                    getData();
                }
            }
        });
    }
    else
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            recyclerView.setOnScrollChangeListener( new RecyclerView.OnScrollChangeListener()
            {
                @Override
                public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                    if (isLastItemDisplaying(recyclerView)) {
                        getData();
                    }
                }
            });
        }
    }

    //initializing our adapter
    adapter = new CustomAdapter(productsList, getActivity());
    //Adding adapter to recyclerview
    recyclerView.setAdapter(adapter);
    return view ;
}

和 customAdapter 类:

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {

//Imageloader to load image
private ImageLoader imageLoader;
private Context context;


List<MyProducts> myProducts;

public CustomAdapter(List<MyProducts> myProducts, Context context)
{
    super();
    this.myProducts = myProducts;
    this.context = context;
}

@Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.product_list, parent, false);
    ViewHolder viewHolder = new ViewHolder(v);
    return viewHolder;
}

@Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {

    if( myProducts != null) {
        MyProducts myProducts1 = myProducts.get(position);
        imageLoader = ImageVolley.getInstance(context).getImageLoader();
        imageLoader.get(myProducts1.getProductImage(), ImageLoader.getImageListener(holder.imageView, R.drawable.android_store_log, android.R.drawable.ic_dialog_alert));

        //Showing data to the views
        holder.imageView.setImageUrl(myProducts1.getProductImage(), imageLoader);
        holder.textViewProductTitle.setText(myProducts1.getProductTitle());
        holder.textViewProductDescription.setText(myProducts1.getProductDescription());
        holder.textViewProductSerialNumber.setText(myProducts1.getProductSn());
        holder.textViewProductPrice.setText(myProducts1.getProductPrice());
    }
}

@Override
public int getItemCount() {
    return myProducts.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {

    //Views
    public NetworkImageView imageView;
    public TextView textViewProductTitle;
    public TextView textViewProductDescription;
    public TextView textViewProductSerialNumber;
    public TextView textViewProductPrice;

    //Initializing Views
    public ViewHolder(View itemView) {
        super(itemView);
        imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero);
        textViewProductTitle = (TextView) itemView.findViewById(R.id.textViewProductTitle);
        textViewProductDescription = (TextView) itemView.findViewById(R.id.textViewProductDescription);
        textViewProductSerialNumber = (TextView) itemView.findViewById(R.id.textViewProductSerialNumber);
        textViewProductPrice = (TextView) itemView.findViewById(R.id.textViewProductPrice);
    }
}

【问题讨论】:

  • LOG 消息中的内容是什么?
  • 没有例外,只有对数组结束的凌空响应,但我仍然在日志中得到了这个:I/Choreographer:跳过了 38 帧!应用程序可能在其主线程上做了太多工作。
  • 确保您的 Frag 在您导航时出现。每次在 recyclerView 中加载数据时都执行recyclerView.notifydatasetchanged();

标签: android android-fragments android-viewpager android-recyclerview android-viewholder


【解决方案1】:

试试这个:

viewPager.setOffscreenPageLimit(3);

设置在空闲状态下视图层次结构中当前页面任一侧应保留的页面数。超出此限制的页面将在需要时从适配器重新创建。

setOffscreenPageLimit

【讨论】:

    猜你喜欢
    • 2021-03-19
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多