【问题标题】:Changing a view's state in RecyclerView在 RecyclerView 中更改视图的状态
【发布时间】:2018-01-14 07:22:27
【问题描述】:

目标:我想更改我在 RecyclerView 中的 progressBar's 可见性,以表明当用户使用 addImage() 添加图像时,图像正在加载。

问题: addImage 应该改变 progressBar's 的可见性。但是,调用addImage()时不会创建Viewholder,所以progressBar是未定义的。

MainActivity

    recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
    GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
    recyclerView.setLayoutManager(gridLayoutManager);

    recyclerView.setAdapter(galleryAdapter);

    if (getArguments() != null) {
        if (getArguments().containsKey(PhotoFragment.IMAGE_URI)) {
            final Uri imageUri = Uri.parse(getArguments().getString(PhotoFragment.IMAGE_URI));
            galleryAdapter.addImage(imageUri);
            galleryAdapter.notifyDataSetChanged();
            getArguments().remove(PhotoFragment.IMAGE_URI);
        }
    }

RecyclerView(问题所在)

public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.GalleryViewHolder> {


ArrayList<Uri> imageUriArrayList = new ArrayList<>();
File[] listFile;
ProgressBar progressBar;
private GalleryFragment mFragment;
private String airBnbDirectory = "/Airbnb";
SharedPreferences sharedPreferences;
SharedPreferences.Editor edit;

public GalleryAdapter(GalleryFragment fragment) {
    mFragment = fragment;
    loadSDCard();
}

public void addImage(final Uri imageUri) {
    imageUriArrayList.add(imageUri);

    //Save image in SD CARD(External Storage)
    new AsyncTask<Void, Void, Void>() {
        //
        String imageUriForLoadingSP;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.d("adapter", "OnPreExecute");
            progressBar.setVisibility(View.VISIBLE);
            //Cannot get progressBar because it's not created by the ViewHolder yet.
        }

        @Override
        protected Void doInBackground(Void... params) {
            imageUriForLoadingSP = saveInSDCard(imageUri);
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            Log.d("mattSaving", "onPostExecute");
            progressBar.setVisibility(View.GONE);

        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);


}




}

@Override
public GalleryAdapter.GalleryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.gallery_adapter_item, parent, false);
    return new GalleryAdapter.GalleryViewHolder(view);
}

@Override
public void onBindViewHolder(GalleryAdapter.GalleryViewHolder holder, int position) {
    holder.bindView(position);
}

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

public class GalleryViewHolder extends RecyclerView.ViewHolder {
    ImageView ivPhoto;

    public GalleryViewHolder(View itemView) {
        super(itemView);
        Log.d("adapter", "ViewHolder");
        ivPhoto = (ImageView) itemView.findViewById(R.id.ivPhoto);
        progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar);

    }

    public void bindView(final int position) {
        //load images called by addImage()
        Glide.with(mFragment)
                .load(imageUriArrayList.get(position)) // Uri of the picture
                .into(ivPhoto);

    }

}

   }

【问题讨论】:

    标签: android android-recyclerview android-viewholder


    【解决方案1】:

    您必须调用 notifyItemChanged(position) 来更新视图项。

    public void addImage(final Uri imageUri) {
        imageUriArrayList.add(imageUri);
    
    //Save image in SD CARD(External Storage)
    new AsyncTask<Void, Void, Void>() {
        //
        String imageUriForLoadingSP;
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.d("adapter", "OnPreExecute");
            progressBar.setVisibility(View.VISIBLE);
            //Cannot get progressBar because it's not created by the ViewHolder yet.
        }
    
        @Override
        protected Void doInBackground(Void... params) {
            imageUriForLoadingSP = saveInSDCard(imageUri);
            return null;
        }
    
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            Log.d("mattSaving", "onPostExecute");
            progressBar.setVisibility(View.GONE);
    
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
    
    
    }
    

    你可以把这个 notifyItemChanged(position);在 imageUriArrayList.add(imageUri) 下;但是你必须提供一个位置,或者你可以尝试在那里使用 notifyDataSetChanged。不知道这将如何工作。

    【讨论】:

    • 谢谢,但出于学习目的,我将坚持使用 progressBar 的想法。任何想法如何在不删除进度条的情况下解决问题?
    • 我现在可以在没有空指针异常的情况下调用progressBar!但是我添加的最新图像中似乎出现了progressBar dosent。相反,它出现在以前保存的图像中,有什么线索吗?
    • 你能更新你当前的代码吗?所以我可以看到变化?
    • 我添加了 notifyDataSetChanged();但我也尝试了 notifyItemChanged(position) ,它们都产生相同的结果。奇怪的是,每当再次创建 ViewHolder 时,progressBar 似乎会从一个图像跳到另一个图像。
    • 这就是我想在这些情况下使用 notifyItemChanged(position) 的原因。 notifyDataSetChanged 倾向于重新创建整个视图列表。我认为您应该使用 notifyItemChanged(position) 并检查该位置是否是进度条的 setVisibility(View.VISIBLE) 的最后一个位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 2021-04-25
    相关资源
    最近更新 更多