我从服务器接收新项目数据并将其设置为我的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);
}
}
答案 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();
}