简体   繁体   English

adapter.notifyDataSetChange()在从另一个活动返回后不更新列表视图

[英]adapter.notifyDataSetChange() not updating the listview after returning from another activity

I have two Activities: 1. contains the listview (Activity1), 2. details of each row in the listview (Activity2). 我有两个活动:1。包含listview(Activity1),2。listview(Activity2)中每行的详细信息。

When the user clicks on any row of the listview in Activity1, its respective details get displayed in Activity2 ie Activity2 is started. 当用户单击Activity1中列表视图的任何行时,其各自的详细信息将显示在Activity2中,即启动Activity2。 When the user edits some details in Activity2, all changes are saved to the server and when I return to Activity1 I am fetching the new(updated) list from the server and want to update the UI (listview) of Activity1. 当用户在Activity2中编辑一些细节时,所有更改都保存到服务器,当我返回到Activity1时,我从服务器获取新的(更新的)列表并想要更新Activity1的UI(列表视图)。 But this does not happen. 但这不会发生。 I am doing the following to update the listview: 我正在做以下更新列表视图:

@Override
protected void onStart() {
    super.onStart();
    Toast.makeText(this, "onStart", Toast.LENGTH_LONG).show();
    PetService petService = FactoryMaker.getFactory(AppConstants.PET_SERVICE).getPetServiceImpl(AppConstants.PARSE_IMPL, this);
    //pets = petService.getPetList();
    //adapter = new PetListArrayAdapter(getApplicationContext(),R.layout.pet_list_item, pets);
    //petListView.setAdapter(adapter);

    pets = petService.getPetList();
    adapter.clear();
    adapter.addAll(pets);
    adapter.notifyDataSetChanged();

    if(pets.size()>0) {
        retrieve.setVisibility(View.INVISIBLE);
    }else{
        retrieve.setVisibility(View.VISIBLE);
    }
}

However if I set the adapter again(like the three lines I commented out), the listview gets updated as required but with notifyDataSetChanged(), its not working. 但是,如果我再次设置适配器(就像我注释掉的三行),listview会根据需要更新,但是使用notifyDataSetChanged(),它不起作用。 I have followed all the questions for this problem but nothing seems to work. 我已经关注了这个问题的所有问题,但似乎没有任何效果。 My adapter extends from ArrayAdapter. 我的适配器从ArrayAdapter扩展。 Please help! 请帮忙!

My adapter implementation: 我的适配器实现:

public class PetListArrayAdapter extends ArrayAdapter<Pet> {

     private final String TAG="PetListArrayAdapter";

     private List<Pet> pets = null;
     private Context applicationContext =null;

     public PetListArrayAdapter(Context context, int resource, List<Pet> petList) {
          super(context, resource, petList);
          pets = petList;
          applicationContext = context;
     }

     @Override
     public int getCount(){
          int size = 0;
          if(pets!=null) {
             size = pets.size();
          }
          return size+1;
     }

     @Override
     public int getItemViewType(int position) {
          return (position == 0) ? 0 : 1;
     }

     @Override
     public int getViewTypeCount() {
          return 2;
     }


     @Override
     public View getView(int position, View convertView, ViewGroup parent)  {
         Log.d(TAG, "getView for position" + position);
         int type = getItemViewType(position);
         LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         if(convertView==null) {
              if(type==1) {
                  convertView = inflater.inflate(R.layout.pet_list_item, null);
                  TextView t = (TextView)convertView.findViewById(R.id.petName);
                  final Pet pet = pets.get(position-1);
                  Log.d(TAG, "pet:" + pet);
                  t.setText(pet.getName());

                  ImageView petImage =(ImageView)convertView.findViewById(R.id.petImage);

                  String imageUrl = pet.getThumbnailUrl();
                  //if(petImage.getDrawable()==null) {
                  if (imageUrl != null) {
                       Log.d(TAG, "Loading Image for position" + position);
                       new ImageDownloader(petImage).execute(imageUrl);
                  }
             /*}else{
             Log.d(TAG, "Image present for position" + position);
             }*/
          }else if (type==0){
               convertView = inflater.inflate(R.layout.add_pet, null);
          }
       }

       return convertView;
   }
}

Try 尝试

pets.clear();
pets.addAll(petService.getPetList());
adapter.notifyDataSetChanged();

I guess the adapter list looses its link to the actual list. 我想适配器列表会丢失它到实际列表的链接。

Add your fetching code in on resume 在简历中添加您的提取代码

@Override
    protected void onResume() {
        super.onResume();

        pets = petService.getPetList();
        adapter.clear();
        adapter.addAll(pets);
        adapter.notifyDataSetChanged();

        if(pets.size()>0) {
            retrieve.setVisibility(View.INVISIBLE);
        }else{
            retrieve.setVisibility(View.VISIBLE);
        }
    }
  1. First of, Start Activity2 using the startActivityForResult(intent,requesCode) instead of the startActivity(intent) method. 首先,使用startActivityForResult(intent,requesCode)而不是startActivity(intent)方法启动Activity2。
  2. Override/implement the onActivityResult(int requestCode, int resultCode, Intent data) of Activity1 and execute these codes. 覆盖/实现Activity1的onActivityResult(int requestCode,int resultCode,Intent data)并执行这些代码。 This will ensure that onBackPressed your list gets updated 这将确保onBackPressed您的列表得到更新

    pets.clear(); pets.clear(); pets.addAll(petService.getPetList()); pets.addAll(petService.getPetList()); adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();

so your codes will look like 所以你的代码看起来像

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //...some codes

    pets.clear();
    pets.addAll(petService.getPetList());
    adapter.notifyDataSetChanged();

}


I tested with this adapter and it works on my side. 我用这个适配器进行了测试,它在我这边工作。 However, I did not have images attached but it should be working fine. 但是,我没有附加图像但它应该工作正常。

public class CustomArrayAdapter extends ArrayAdapter<Pet> {
    private final String TAG = "PetListArrayAdapter";

    private List<Pet> pets = null;

    public CustomArrayAdapter(Context context, List<Pet> petList) {
         super(context, 0, petList);
         pets = petList;
    }

    @Override
    public int getCount() {
        int size = 0;
        if (pets != null) {
            size = pets.size() + 1;
        }
        return size;
    }

    @Override
    public int getItemViewType(int position) {
         return (position == 0) ? 0 : 1;
    }

    @Override
    public int getViewTypeCount() {
         return 2;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
         Log.d(TAG, "getView for position" + position);
         ViewHolder holder;
         int type = getItemViewType(position);
         LayoutInflater inflater = LayoutInflater.from(getContext());
         if (convertView == null) {
             holder = new ViewHolder();
             if (type == 1) {
                 convertView = inflater.inflate(R.layout.list_item_layout, null);
                 holder.tvName = (TextView) convertView.findViewById(R.id.tv_name);
                 holder.tvDescription = (TextView) convertView.findViewById(R.id.tv_descriotion);
                 final Pet pet = pets.get(position - 1);
                 Log.d(TAG, "pet:" + pet);

                convertView.setTag(holder);
             } else if (type == 0) {
                  convertView = inflater.inflate(R.layout.list_add_layout, null);
                  holder.tvName = (TextView) convertView.findViewById(R.id.tv_add);
             }
        } else {
             holder = (ViewHolder) convertView.getTag();
        }
        if (holder != null) {
             if (type == 1) {
                 holder.tvName.setText(pets.get(position - 1).getName());
                 if (holder.tvDescription != null) {
                    holder.tvDescription.setText(pets.get(position - 1).getDescription());
                 }
             } else if (type == 0) {
                 holder.tvName.setText("Add new pet");
             }
         }

         return convertView;
     }
     static class ViewHolder {
         TextView tvName;
         TextView tvDescription;
     }
 }

I must add that you need to have a proper holder to handle the add pet layout and the layout for pets. 我必须补充一点,你需要有一个合适的持有人来处理宠物的添加宠物布局和布局。 What I added here it is just a starting point for you. 我在这里添加的只是你的起点。 I would create base holder containing one textview or nothing and use specific holders for specific types and you cast to the right holder whenever it is type 1 or 0. 我会创建包含一个textview或没有任何内容的基本持有者,并使用特定类型的特定持有者,并且只要它是类型1或0,就会转换为权利持有者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM