为啥异步不会停止重新创建列表视图?

Posted

技术标签:

【中文标题】为啥异步不会停止重新创建列表视图?【英文标题】:Why isn't async stopping from recreating listview?为什么异步不会停止重新创建列表视图? 【发布时间】:2017-10-08 09:26:24 【问题描述】:

不知道怎么问这个,但是...

我的代码旨在在单击按钮时生成 ListView 输入。

当我单击按钮时,它应该 .execute() 一个 Async,它接受一个项目列表并将它们添加到一个带有自定义适配器的 ArrayList>。

问题是,当我按下按钮时,它会生成列表并将其添加到 ListView,但是,它没有进入... 1, 2, 3, 4, 5, ....20 它进入一个随机的顺序。 1, 2, 5, 1, 3, 0, 6, 7, 8, 3, 1 ...

如果我向上或向下滚动 ListView,它会发生变化。

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_
    android:layout_
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/bLoadData"
        android:layout_
        android:layout_
        android:layout_alignParentBottom="true"
        android:text="Load api data" />

    <ListView
        android:id="@+id/lvMovies"
        android:layout_
        android:layout_
        android:layout_above="@id/bLoadData"
        android:background="#efefef" />

</RelativeLayout>

results_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="vertical">

    <LinearLayout
        android:layout_
        android:layout_
        android:orientation="horizontal">


        <ImageView android:id="@+id/ivPosters"
            android:layout_
            android:layout_
            android:src="@drawable/place_holder_img"/>

        <TextView
            android:id="@+id/results_layout_tv_movie_name"
            android:layout_
            android:layout_
            android:layout_weight="1"
            android:paddingBottom="10dp"
            android:paddingLeft="20dp"
            android:paddingStart="20dp"
            android:paddingTop="10dp"
            android:text="hellow"
            android:textColor="#000"
            android:textSize="20sp" />

    </LinearLayout>
</LinearLayout>

MainActivity.class:

package com.example.zdroa.testinggrounds;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity 

    static ArrayList<HashMap<String, String>> posters;
    ListView listView;
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = (ListView) findViewById(R.id.lvMovies);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 

            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
                System.out.println(posters.get(position).values().toString());
            
        );

        button = (Button) findViewById(R.id.bLoadData);
        button.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                posters = new ArrayList<>();
                ImageLoadTask ilt = new ImageLoadTask();
                ilt.execute();
            
        );
    


    private class ImageLoadTask extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> 

        @Override
        protected ArrayList<HashMap<String, String>> doInBackground(Void... params) 

            posters = getPathFromAPI();
            return posters;
        

        @Override
        protected void onPostExecute(ArrayList<HashMap<String, String>> result) 
            SearchAdapter adapter = new SearchAdapter(MainActivity.this, result);
            listView.setAdapter(adapter);
        

        private ArrayList<HashMap<String, String>> getPathFromAPI() 
            String moviePaths[] = new String[10];

            for (int i = 0; i < moviePaths.length; i++) 
                HashMap<String, String> map = new HashMap<>();
                String s = "path";
                map.put(s, s + "_" + i);
                moviePaths[i] = "path_" + i;
                posters.add(map);
            
            return posters;
        
    

SearchAdapter.class:

package com.example.zdroa.testinggrounds;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.HashMap;

public class SearchAdapter extends BaseAdapter 

    private Context mContext;
    private ArrayList<HashMap<String, String>> array;
    private ImageView imageView;
    private TextView textView;

    SearchAdapter(Context context, ArrayList<HashMap<String, String>> paths) 
        mContext = context;
        array = paths;
    

    @Override
    public int getCount() 
        return array.size();
    

    @Override
    public Object getItem(int position) 
        return null;
    

    @Override
    public long getItemId(int position) 
        return 0;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 

        if (convertView == null) 
            convertView = View.inflate(mContext, R.layout.results_layout, null);
            imageView = (ImageView) convertView.findViewById(R.id.ivPosters);
            textView = (TextView) convertView.findViewById(R.id.results_layout_tv_movie_name);
        

        Drawable drawable = ContextCompat.getDrawable(mContext, R.drawable.place_holder_img);

        String link_end = array.get(position).values().toString();
        Picasso.with(mContext)
                .load("http://image.tmdb.org/t/p/w185" + link_end)
//                .resize(width, (int) (width * 1.5))
                .placeholder(drawable)
                .into(imageView);


        textView.setText(position+"");

        return convertView;
    

【问题讨论】:

如果我将 ImageView 中的图像大小从 120 x 120dp 更改为 50 x 50dp,结果为 10,则问题不会发生,但如果我也将结果从 10 更改为 20,它会再次发生 你应该只生成 10 个项目的代码,而不是 20 个。并且每次它都按顺序生成它们。问题出在其他地方 您的 imageview 和 textview 引用仅在 convertview 为空时设置...将这些行移出括号。 @ElDuderino 将问题回复为答案,以便我将其标记为正确 【参考方案1】:

您的 imageview 和 textview 引用仅在 convertview 为空时设置...将这些行移出括号。

【讨论】:

【参考方案2】:

在 Asyntask 类的 onPost 中

在为列表视图创建和设置适配器之后 在列表视图中制作您正在使用的列表

list=new ArrayList<>();

【讨论】:

以上是关于为啥异步不会停止重新创建列表视图?的主要内容,如果未能解决你的问题,请参考以下文章

为啥单击 SwiftUI 中的列表项后列表视图项变为灰色?

为啥当我在目标 c 中重新加载表视图时选择的值会被取消选择

iOS 为啥我的应用程序在重新启动之前不会将数据加载到 tableview 中?

tableview 不会从第二类正确重新加载

重新加载表视图数据并取消选择单元格

颤振:如何在不按按钮的情况下进行列表视图更新?