Динамическое изменение изображения в динамическом списке на Android

Я создал приложение с listview с arrayadapter, которое пользователь может динамически заполнять. Я сохраняю информацию, введенную в качестве строки json в настройках, и когда я обновляю приложение, я получаю список с записями. Дело в том, что я хочу, чтобы изображение рядом с каждой записью менялось после сетевой операции. Проблема, с которой я сталкиваюсь, кажется, заключается в том, что, поскольку элементы в списке добавляются динамически, я, кажется, не нахожу хорошего способа ни обновить imageview на onPostExecute() метод, либо иметь возможность целевой каждой записи специально, так как они имеют те же идентификаторы макета.

Вот мой метод getView () внутри адаптера:

   @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.product_list_item, null);
            holder = new ViewHolder();
            holder.deviceName = (TextView) convertView
                    .findViewById(R.id.txt_pc_name);
            holder.deviceIp = (TextView) convertView
                    .findViewById(R.id.txt_pdt_desc);
            holder.devicePort = (TextView) convertView
                    .findViewById(R.id.txt_pdt_price);
            holder.favoriteImg = (ImageView) convertView
                    .findViewById(R.id.imgbtn_favorite);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Devices device = (Devices) getItem(position);
        holder.deviceName.setText(device.getName());
        holder.deviceIp.setText(device.getIpOnline());
        holder.devicePort.setText(device.getPortOnline() + "");              


        return convertView;
    }

Вот мой AsyncTask:

public class Connection extends AsyncTask<String, Void, String> {

   private String ipOnline;
   private int portOnline;
   private String ipWol;
   private int portWol;
   private String macAddress;
   private ImageView img;
   private Context context;
    public interface AsyncResponse {
        void processFinish(String output);
    }



     public AsyncResponse delegate = null;

        public Connection(Context mContext, ImageView Img,String IpOnline, int PortOnline, String IpWol, int PortWol, String MacAddress, AsyncResponse delegate) {
            ipOnline = IpOnline;
            portOnline = PortOnline;
            ipWol = IpWol;
            portWol = PortWol;
            macAddress = MacAddress;
            context = mContext;
          //  inflate = Inflate;
            img = Img;
           // spin = spinner;
            this.delegate = delegate;
        }
        public int status;

        @Override
       protected String doInBackground(String... arg0) {PreferenceManager.getDefaultSharedPreferences(lastContext);
            try  {
                Socket echoSocket = new Socket();
                echoSocket.connect(new InetSocketAddress(ipOnline,portOnline),2000);

                if(echoSocket.isConnected())
                    status = 1;
            } catch (Exception e) {
                status = 0;
            }
            if(status == 0)
                return "0";
            else
                return "1";
       }

        @Override
        protected void onProgressUpdate(Void... values) {}

       @Override
       protected void onPostExecute(String result) {           
           super.onPostExecute(result);
ImageView img = (ImageView) activity.findViewById(R.id.imgbtn_favorite);
               if (status == 0)
                   img.setImageResource(android.R.drawable.presence_offline);
               else
                   img.setImageResource(android.R.drawable.presence_online);
    delegate.processFinish(result);  
       }   
    }

И вот мой призыв к нему:

new Connection(activity, img, product.getIpOnline(), Integer.parseInt(product.getPortOnline()), product.getIpWol(), Integer.parseInt(product.getPortWol()), product.getMacAddress(), new Connection.AsyncResponse() {
                        @Override
                        public void processFinish(String output) {
                        }
                    }).execute();

2 ответа

  1. Можно использовать шаблон держателя вида или recyclerview .

    Вы должны сохранить ссылку на представление изображения в держателе и можете обновить изображение с помощью этой ссылки вместо идентификатора представления

  2. Я придумал решение.

    Я создал открытую переменную на моем адаптере, и я добавляю все образы:

    public List<ImageView> allImages = new ArrayList<ImageView>();
    
    public List<ImageView> getAllImages(){
            return this.allImages;
        }
    
    this.allImages.add((ImageView) convertView
                    .findViewById(R.id.imgbtn_favorite));
    

    Затем в моем фрагментированном методе onCreateView действия я развернул отложенное выполнение:

    (new Handler()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        updateStatus();
                    }
                }, 500);
    

    метод updateStatus () инициализирует переменную images и начинает проверку сети, чтобы определить, какой образ использовать. Затем он применяет его соответствующим образом.

    public void updateStatus() {
            List<ImageView> images = deviceListAdapter.getAllImages();
            if(count > 0 && images.size() > 0) {
                for (int i = 0; i < deviceListAdapter.getCount() ; i++) {
                    Devices product = (Devices) deviceListAdapter.getItem(i);
                    if((TextUtils.isDigitsOnly(product.getPortOnline()) && TextUtils.isDigitsOnly(product.getPortWol())) && (!product.getPortOnline().isEmpty() && !product.getPortWol().isEmpty()))  {
                        new Connection(activity, images.get(i), product.getIpOnline(), Integer.parseInt(product.getPortOnline()), product.getIpWol(), Integer.parseInt(product.getPortWol()), product.getMacAddress(), new Connection.AsyncResponse() {
                            @Override
                            public void processFinish(Boolean output) {
                            }
                        }).execute();
                    }
                }
            }
        }
    

    Это может быть не оптимальным, но не стесняйтесь, чтобы добавить лучшее решение.