ProgressBar INVISIBLE
Есть список изображений, сделанный через RecyclerView. Когда вы нажимаете на изображение, в то время пока оно передается в следующую активити, должен отображаться ProgressBar. Когда происходит возврат к активности выбора изображения, ProgressBar также остается видимым, хотя он должен быть скрыт.
Как я сделал ниже, прогресс становится невидимым только на первом изображении, но на остальных он не работает(остается видимым). Я не могу понять почему
в моем проекте есть такие классы как
interface
public interface ImageOnC {
void onClick(int position);
}
ImageViewHolder
public class ImageViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
private ImageOnC imageOnC;
public ImageButton imageButton;
public ProgressBar progressBar;
public void setImageOnC(ImageOnC imageOnC) {
this.imageOnC = imageOnC;
}
public ImageViewHolder(@NonNull final View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.image_outline);
progressBar = itemView.findViewById(R.id.progr);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
imageOnC.onClick(getAdapterPosition());
progressBar.setVisibility(View.VISIBLE);
}
});
}
}
ImageAdabter
public class ImageAdabter extends RecyclerView.Adapter<ImageViewHolder> {
private Context mContext;
private List<Integer> listImages;
public ImageAdabter(Context mContext){
this.mContext = mContext;
this.listImages = getImages();
}
private List<Integer> getImages() {
List<Integer> results = new ArrayList<>();
results.add(R.drawable.outline1);
results.add(R.drawable.outline2);
results.add(R.drawable.outline3);
results.add(R.drawable.outline4);
results.add(R.drawable.outline5);
results.add(R.drawable.outline6);
results.add(R.drawable.outline7);
results.add(R.drawable.outline8);
results.add(R.drawable.outline9);
results.add(R.drawable.outline10);
return results;
}
@NonNull
@Override
public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_images,parent,false);
return new ImageViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final ImageViewHolder holder, final int position) {
holder.imageView.setImageResource( listImages.get(position));
holder.setImageOnC(new ImageOnC() {
@Override
public void onClick(int position) {
Common.PICTURE_SELECTED = listImages.get(position);
mContext.startActivity(new Intent(mContext, Colorful.class));
}
});
@Override
public void onBindViewHolder(@NonNull ImageViewHolder holder, int position, List<Object>payload){
//if so, then the progress bar only works for the first image in recyclerview
if(!payload.isEmpty()){
if(payload.get(position) instanceof Integer)
holder.progressBar.setVisibility(View.GONE);
}
else super.onBindViewHolder(holder, position, payload);
}
@Override
public int getItemCount() {
return listImages.size();
}
}
Это я добавляю в активити
private void initView() {
recyclerView = findViewById(R.id.recycle_view_images);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adabter = new ImageAdabter(this);
recyclerView.setAdapter(adabter);
}
@Override
public void onResume() {
super.onResume();
if (adabter != null) {
adabter.notifyItemChanged(position, position);
}
}
Если делать таким образом, то прогрессбар работает как нужно только у первого изображения..
Ответы (2 шт):
Насколько я вижу из кода у вас список на базе recyclerView. Я думаю что нужно использовать такую штуку как notifyItemChanged. В конструктор вы передаете интерфейс который нужен для того чтобы адаптер как-то был связан с активностью. Поэтому вероятнее всего ваша активность имеет функцию onClick или что-то типа того, куда вы передаете позицию картинки. Следовательно позиция у вас есть и вы можете вызвать такой метод:
adapter.notifyItemChanged(position, 0)
дальше в адаптере списка нужно переопределить метод:
@Override
public void onBindViewHolder(HelloViewHolder holder, int position, List<Object> payload) {
if(!payloads.isEmpty()) {
if (payloads.get(0) instanceof Integer) {
holder.progressBar.visibility = View.GONE;
}
}else {
super.onBindViewHolder(holder,position, payloads);
}
}
таким образом как только вы передали данные в активность, то вы сразу скрываете ваш лоадер.
И я бы вам советовал сделать обработку картинки в методу onBindViewHolder так как там будет удобнее брать position картинки.
Вашему адаптеру в конструкторе не нужен ни контекст ни список.
Так же будет правильно реализовывать клик во фрагменте/активити просто передавая через интерфейс ссылку на айтем.
Контекст для картинок можно брать у любой вью, так же и список передавать в конструктор вовсе не нужно. Вместо этого можно создать внутри адаптера метод, например такой :
fun setData(item: List<Integer>){
listImages.clear()
listImages.addAll(item)
notifyDataSetChanged()
}
и создавать адаптер проще :
adapter = new Adapter()
и добавлять данные :
adapter.getData(listImages)
В этот же момент каждый раз адаптер будет получать notifyDataSetChange() Ну и следовательно там же можно установить флаг на показ прогресс бара. можно ,как советовали выше создать еще методы для обновления удаления итд.
к примеру вам нужно сделать какой то метод в котором либо показывать либо прятать прогресс бар только там где нужно. Если речь идет о адаптере, то пользоваться позицией. Например
override fun showProgress(show: Boolean) {
if (show) {
progressBar.visibility = VISIBLE;
} else {
progressBar.visibility = GONE;
}
}
соответственно обновленный метод будет выглядить так
fun setData(item: List<Integer>){
listImages.clear()
listImages.addAll(item)
showProgress(false)
notifyDataSetChanged()
}
Вообще вся эта идея с показом выглядит как костыль, но можно еще прикрутить таймер для показа видимости на секунду две)))) Можно прикрутить еще таймер для видимости загрузки на пару секунд как костыль.
Ну а показывать нужный по позиции как вы и делали/
Так же, если нужно показывать загрузку пока загружаются картинки и вообще для загрузки картинок в целом можно воспользоваться PICASSO или GLIDE Специально обученные люди специально обученным инструменами сделали их специально для загрузки изображений. Там есть свои коллбэки для отработки этих событий
try {
if (urlToImage != null && urlToImage.isNotEmpty()) {
Picasso.get()
.load(urlToImage)
.placeholder(R.drawable.placehoder)
.fit()
.centerCrop()
.into(holder.image, object : Callback {
override fun onSuccess() {
if (holder.progressBar != null) {
holder.progressBar.visibility = View.GONE
}
}
override fun onError(e: Exception) {}
})
}