RecyclerView:新加载的商品不会添加到顶部

时间:2016-04-23 15:50:12

标签: android android-asynctask android-recyclerview adapter

我从服务器接收新项目数据并将其设置为我的RecyclerView适配器。当我第一次启动异步任务以获取数据时,从顶部显示所获取的数据。但是,当我再次启动异步任务以获取新数据时,新数据将附加在(不可见的)旧数据下方,尽管我在启动服务器请求之前设置了adapter = null

一般过程:

1)启动Activity和AsyncTask以从服务器获取数据:asynctask.execute();

2)致电mRecyclerView.setAdapter(mAdapter);mAdapter.notifyDataSetChanged();,数据将从顶部显示

3)再次启动asynctask:首先设置mAdapter = null;并加载另一个数据

3)中的问题:现在新加载的数据不会从顶部显示,而是低于1)中的数据,但由于mAdapter = null;而不再显示。这就像RecyclerView没有“删除”1)中显示的旧数据的空间。

这很奇怪,有人知道为什么会出现这种情况吗?

代码:

a)我的适配器:

public class Adapter_New extends RecyclerView.Adapter<Adapter_New.CustomViewHolder> {

    private List<Data_B> feedItemList;
    private Context mContext;
    private int lastPosition = -1, b_height;
    int width, height, targetHeight;
    private ViewHolderState viewHolderState = ViewHolderState.getInstance();


    public Adapter_New(Context context, List<Data_B> feedItemList) {
        this.feedItemList = feedItemList;
        this.mContext = context;
    }

    @Override
    public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();

        int calc_width= metrics.widthPixels;
        int calc_height=metrics.heightPixels;
        int dens=metrics.densityDpi;
        double wi=(double)calc_width/(double)dens;
        double hi=(double)calc_height/(double)dens;
        double x = Math.pow(wi,2);
        double y = Math.pow(hi,2);
        double screenInches = Math.sqrt(x + y);

        if (screenInches >= 7.0){
            width = metrics.widthPixels/3;
            height = metrics.heightPixels / 4;
        }else{
            width = metrics.widthPixels/2;
            height = metrics.heightPixels / 4;
        }


        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item_grid, null);
        CustomViewHolder viewHolder = new CustomViewHolder(view);


        return viewHolder;
    }


    @Override
    public void onViewDetachedFromWindow(CustomViewHolder holder) {
        super.onViewDetachedFromWindow(holder);
        ((CustomViewHolder) holder).clearAnimation();
        ((CustomViewHolder) holder).cleanup();
    }

    @Override
    public void onBindViewHolder(final CustomViewHolder customViewHolder, int i) {

        Data_Borrow data = feedItemList.get(i);

        final Target target = new Target() {

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }

            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                b_height = bitmap.getHeight();

                customViewHolder.frame.getLayoutParams().height = b_height; //setting height dynamically
                customViewHolder.imageView.getLayoutParams().height = b_height; //setting height dynamically
                customViewHolder.imageView.setImageBitmap(bitmap);
            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {
            }


        };

        customViewHolder.imageView.setTag(target);

        Picasso.with(mContext)
                .load(data.getImageUrl())
                .resize(width, height)
                .into(target);

        // Animation apply
        setAnimation(customViewHolder.rel_container, i);

    }

    //Animation
    private void setAnimation(View viewToAnimate, int position) {
        // If the bound view wasn't previously displayed on screen, it's animated
        if (position > lastPosition) {
            Animation animation = AnimationUtils.loadAnimation(mContext, R.anim.slide_in_up);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }


    @Override
    public int getItemCount() {
        return (null != feedItemList ? feedItemList.size() : 0);
    }


    public void add_new(List<Data_Borrow> datas) {

        //feedItemList.clear();
        feedItemList.addAll(datas);
        notifyDataSetChanged();
    }

    public void clear() {

        feedItemList.clear();
        notifyDataSetChanged();
    }


    public class CustomViewHolder extends RecyclerView.ViewHolder {
        protected ImageView imageView;
        protected RelativeLayout rel_container;
        protected FrameLayout frame;
        protected CardView card_view;

        public CustomViewHolder(View view) {
            super(view);
            this.imageView = (ImageView) view.findViewById(R.id.thumbnail);
            this.title = (TextView) view.findViewById(R.id.title);
            this.rel_container = (RelativeLayout) view.findViewById(R.id.rel_grid_item);
            this.frame = (FrameLayout) view.findViewById(R.id.frame_current);
            this.frame.getLayoutParams().width = width; //setting width dynamically
            this.card_view = (CardView) view.findViewById(R.id.card_view);

        }

        public void cleanup() {
            Picasso.with(mContext)
                    .cancelRequest(imageView);
        }


        public void clearAnimation() {
            rel_container.clearAnimation();
        }
    }
}

b)我的活动:

public class MyActivity extends AppCompatActivity implements FetchDataListener, SearchView.OnQueryTextListener, AdapterView.OnItemSelectedListener {

 private List<Data_B> feedsList = null;
 private RecyclerView mRecyclerView;
 private Adapter_New mAdapter;
 StaggeredGridLayoutManager StaggeredGridLayoutManager;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);

         StaggeredGridLayoutManager = new StaggeredGridLayoutManager(3, 1);
         StaggeredGridLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
         mRecyclerView.setAdapter(new Data_Borrow_Adapter_New(this, feedsList)); // first add empty adapter
         mRecyclerView.setLayoutManager(StaggeredGridLayoutManager);

         initView(); //start initView when activity starts

        //******* WHEN I CLICK TO GET NEW FILTERED DATA, then new data is not shown from top on ****//       
        btn_start_filtered_asynctask = (Button) findViewById(R.id.btn_filter);
        btn_start_filtered_asynctask.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              initViewFilterd();
            }
        });

    }


    private void initView() {

        String url = "http://xxx/xx.php";
        String show_from = "0";

        FetchDataTask_ALL task = new FetchDataTask_ALL(this);
        task.execute(url, show_from);

        loading = true;

    }

    private void initViewFilterd() {

        String url = "http://xxx/xx.php";
        String show_from = "0";
        String result_category_pos = "2";

        FetchDataTask_Filtered task = new FetchDataTask_Filtered(this);
        task.execute(url, result_category_pos, show_from);

        mAdapter = null; //setting adapter null 

        loading = true;
    }

    @Override
    public void onFetchComplete(List<Data_B> data) {

    if (mAdapter == null) 

            {
                mAdapter = new Adapter_New(getApplicationContext(), data);
                mRecyclerView.setAdapter(mAdapter);
                mAdapter.notifyDataSetChanged();

            } else {

                mAdapter.add_new(data);

            }

        searchItem.collapseActionView();
        loading = false;
        mRecyclerView.setVisibility(View.VISIBLE);

    }

}

1 个答案:

答案 0 :(得分:0)

你不应该将适配器设置为null,你应该更新适配器中的数据(在你的情况下,在数据源的开头添加新项目(列表,数组,任何东西),然后调用notifyDataSetChanged() < / p>

编辑:我建议更改这两个方法:删除adapter = null,并始终先添加项目。 (您可能需要将该方法添加到适配器)

private void initViewFilterd() {
    String url = "http://xxx/xx.php";
    String show_from = "0";
    String result_category_pos = "2";

    FetchDataTask_Filtered task = new FetchDataTask_Filtered(this);
    task.execute(url, result_category_pos, show_from);

    loading = true;
}

@Override
public void onFetchComplete(List<Data_B> data) {
    mAdapter.addFirstAndUpdate(data);

    searchItem.collapseActionView();
    loading = false;
    mRecyclerView.setVisibility(View.VISIBLE);

}

在适配器中:

public void addFirstAndUpdate(List<Data_Borrow> datas) {
    // TODO: add data in feedItemList
    notifyDataSetChanged();
}