Изображения listView, загруженные с помощью Picasso, обновляются при прокрутке - PullRequest
0 голосов
/ 07 апреля 2020

Я создал просмотр списка, который извлекает данные json с сервера, который содержит URL для извлечения изображения для каждой строки, я использую Picasso для установки изображений, но когда я прокручиваю просмотр списка, он обновляет изображения и иногда просто не ставит их в правильное положение при первой загрузке. вот мой код адаптера:

public class drugs_adaptor_listView extends ArrayAdapter<drugs_json_data> {

ArrayList<drugs_json_data> drugs;
Context context;
int resource;

public drugs_adaptor_listView(Context context, int resource, ArrayList<drugs_json_data> drugs) {
    super(context, resource, drugs);
    this.drugs = drugs;
    this.context = context;
    this.resource = resource;
}

@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View r = convertView;
    ViewHolder viewHolder;

    if(r == null) {
        LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        r = layoutInflater.inflate(R.layout.row_layout_drugs, null, true);
        viewHolder = new ViewHolder(r);
        r.setTag(viewHolder);
    }else{
        viewHolder = (ViewHolder) r.getTag();
    }

    drugs_json_data drugs_json_data = getItem(position);
    viewHolder.txtDrugId.setText(drugs_json_data.getDrugId());
    viewHolder.txtDrugName.setText(drugs_json_data.getDrugName());
    viewHolder.txtDrugCategory.setText(drugs_json_data.getDrugCategory());

    Picasso builder = new Picasso.Builder(context).memoryCache(new LruCache(24000)).build();
    builder.load(drugs_json_data.getDrugImage()).placeholder(R.drawable.ic_launcher_foreground).into(viewHolder.imageView);

    return r;
}

class ViewHolder{
    TextView txtDrugId, txtDrugName, txtDrugCategory;
    ImageView imageView;

    ViewHolder(View v){
        txtDrugId = v.findViewById(R.id.txtDrugId);
        txtDrugName = v.findViewById(R.id.txtDrugName);
        txtDrugCategory = v.findViewById(R.id.txtDrugCat);
        imageView = v.findViewById(R.id.ImageViewDrug);
    }
}

}

и это код действия (только соответствующие части):

publi c класс clerk_drugs extends AppCompatActivity {

ListView listView;
Button createDrug;
String drug_id, json_drug;
TextView noMed;
EditText searchTxt;
JSONObject jsonObject;
JSONArray jsonArray;
ArrayList<drugs_json_data> arrayList;
drugs_adaptor_listView adapter;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_clerk_drugs);
    createDrug = findViewById(R.id.create_drug);
    arrayList = new ArrayList<>();
    listView = findViewById(R.id.list_drugs);
    noMed = findViewById(R.id.no_med);
    searchTxt = findViewById(R.id.listSearch);


    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            try {
                new ReadJSON().execute("http://(the php file link)").get();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });

}

class ReadJSON extends AsyncTask<String, Integer, String>{

    @Override
    protected String doInBackground(String... params) {
        return readURL(params[0]);
    }

    @Override
    protected void onPostExecute(String content) {
        try {
            JSONObject jsonObject = new JSONObject(content);
            JSONArray jsonArray = jsonObject.getJSONArray("server_response");
            for(int i=0; i<jsonArray.length();i++){
                JSONObject drugObj = jsonArray.getJSONObject(i);
                arrayList.add(new drugs_json_data(
                        drugObj.getString("drug_photo"),
                        drugObj.getString("drug_name"),
                        drugObj.getString("drug_category"),
                        drugObj.getString("drug_id")

                ));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        adapter = new drugs_adaptor_listView(
                getApplicationContext(), R.layout.row_layout_drugs, arrayList
        );

        listView.setAdapter(adapter);
        listView.setTextFilterEnabled(true);

        if (adapter.getCount()==0){
            noMed.setVisibility(View.VISIBLE);
        }
    }
}


private String readURL(String theURL) {

    StringBuilder content = new StringBuilder();

    try{
        URL url = new URL(theURL);
        URLConnection urlConnection = url.openConnection();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
        String line;

        while((line=bufferedReader.readLine())!=null){
            content.append(line).append("\n");
        }
        bufferedReader.close();

    }catch (Exception e){
        e.printStackTrace();
    }
    json_drug = content.toString();
    return content.toString();
}

@Override
public void onBackPressed() {
    Intent intent = new Intent(this,patient_mainPage.class);
    startActivity(intent);
}

public void createDrugDialog(View view){
    openDrugDialog();
}

private void openDrugDialog() {
    drug_add_dialog drug_add_dialog = new drug_add_dialog();
    drug_add_dialog.show(getSupportFragmentManager(),"ثبت داروی جدید");
}

}

Решение

После 3 дней стука в голову я мог узнать, что не так в моих кодах, если кто-то из вас По той же проблеме я создавал экземпляр Picasso в getview, поэтому каждый раз, когда пользователь прокручивал список для каждой строки, создавался экземпляр, который занимал много ресурсов и в некоторых случаях вызывал сбой из-за утечки памяти. поэтому я просто переместил конструктор Picasso над getView и просто вызвал его внутри getView:

Picasso builder = new Picasso.Builder(getContext()).build();
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View r = convertView;
    ViewHolder viewHolder;

    if (r == null) {
        LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        r = layoutInflater.inflate(R.layout.row_layout_drugs, null, true);
        viewHolder = new ViewHolder(r);
        r.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) r.getTag();
    }

    drugs_json_data drugs_json_data = getItem(position);
    viewHolder.txtDrugId.setText(drugs_json_data.getDrugId());
    viewHolder.txtDrugName.setText(drugs_json_data.getDrugName());
    viewHolder.txtDrugCategory.setText(drugs_json_data.getDrugCategory());

    builder.load(drugs_json_data.getDrugImage()).memoryPolicy(MemoryPolicy.NO_STORE).placeholder(R.drawable.ic_launcher_foreground).into(viewHolder.imageView);

    return r;
}

Остальное осталось прежним. Надеюсь, это поможет кому-то:)

...