2016-04-23 123 views
0

我正在從服務器接收新項目數據並將其設置爲我的RecyclerView的適配器。當我第一次啓動異步任務來獲取數據時,獲取的數據從頂部顯示。但是當我再次啓動異步任務來獲取新數據時,新數據會附加在(不可見的)舊數據下面,儘管我在開始服務器請求之前設置了adapter = nullRecyclerView:新加載的項目不會添加到頂部

一般方法:

1)啓動活性及的AsyncTask從服務器獲取數據:asynctask.execute();

2)調用mRecyclerView.setAdapter(mAdapter);mAdapter.notifyDataSetChanged();和數據將被從頂部被顯示在

3)initate的AsyncTask再次:第一組mAdapter = null;並加載另一個數據

問題在3):現在新裝DA ta不會從頂部顯示,而是低於1)中的數據,但由於mAdapter = null;而不可見。這就像RecyclerView沒有「刪除」1)中顯示的舊數據的空間。

這很奇怪,有人有任何想法爲什麼會出現這種行爲?


代碼:

一)我的適配器:

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

您可以加入相關的代碼,而不是模糊的描述? – tynn

+0

好的我收錄了我的活動和我的適配器。請參閱更新的問題。 – Sin

+0

爲什麼你在'add_new'中註釋'feedItemList.clear()'? – tynn

回答

0

你不應該設置適配器爲null,則應該更新數據在適配器中(在你的情況下,在數據源的開始處添加新項目(列表,數組,任何東西),然後調用notifyDataSetChanged()

編輯:我建議改變這兩種方法:刪除適配器= 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(); 
} 
+0

請看我更新的問題,我添加了適配器和活動.. – Sin

+0

謝謝你的提示,我刪除了'adapter = null;'現在過濾的數據顯示從頂部...但是怎麼可以我現在檢查'onFetchComplete'如果適配器是空的或不是? – Sin

+0

您可以在檢查feedItemList.isEmpty()的適配器中添加一個方法,但是爲什麼? –

相關問題