【问题标题】:How can I change UI data using an Asynctask class in Android?如何在 Android 中使用 Asynctask 类更改 UI 数据?
【发布时间】:2018-09-10 05:23:06
【问题描述】:

我想知道使用 Asynctask 类 (LocationAsyncTask.java) 和 Activity 更改 UI 数据 (ListView) 的最佳方式是什么。

我有这个异常错误:

Error:(40, 5) error: method does not override or implement a method from a supertype

已编辑:

我有这个 Asynctask 类(LocationAsyncTask.java):

public abstract class LocationAsyncTask extends AsyncTask{

    public ArrayList<Location> locationList;

    public Context context;

    public LocationAsyncTask(Context context) {
        this.context = context;
    }

    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            //These lines are an example(I will obtain the data via internet)
            Location ejemplo = new Location("Locality1","name","address");
            Location ejemplo2 = new Location("Locality2","name2","address2");
            locationList = new ArrayList<Location>();
            locationList.add(ejemplo);
            locationList.add(ejemplo2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {}

}

这是我的 Activity 类:

public class LocationNativeActivity extends Activity {
    ArrayList<Location> locationList;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LocationAsyncTask myTask = new LocationAsyncTask(this){
            @Override
            protected void onPostExecute(Void aVoid) {
                ListView s = (ListView)(findViewById(R.id.lvlocationnative));
                ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(context, android.R.layout.simple_list_item_1, locationList);
                s.setAdapter(adapter);
            }
        };

        myTask.execute();

    }

}

这是我的布局:

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

    <ListView
        android:id="@+id/lvlocationnative"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

这是我的位置类:

public class Location {

    private String addressLocality;
    private String name;
    private String address;

    public Location(String addressLocality,String name, String address) {
        this.addressLocality = addressLocality;
        this.name = name;
        this.address = address;
    }

    public String getAddressLocality() {
        return addressLocality;
    }

    public void setAddressLocality(String addressLocality) {
        this.addressLocality = addressLocality;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return this.addressLocality; 
    }

}

使用此代码我无法在 Listview 中插入数据,有什么建议吗?

我检查了这些帖子:

【问题讨论】:

  • 使用Handler .... 或者只使用onPostExecute()
  • 在 onPostExecute 在 onPreExecute 和 onProgress 方法中你可以更新你的用户界面。
  • 你可以在你的问题中添加 Location 类吗?
  • @Sagar 是的,已添加!谢谢!
  • 你为什么要创建一个没有添加到任何东西的新 ListView?

标签: java android android-activity android-asynctask


【解决方案1】:

您的方法存在很多问题,@Jyoti 刚刚强调了其中一个问题。您不能像使用复杂对象一样简单地使用 ArrayAdapter。它不会产生有用的结果。相反,您需要创建 CustomAdapter。

  1. 创建自定义项目视图让我们说 item_location.xml 在布局文件夹下并输入以下代码:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent" >
        <TextView
            android:id="@+id/tvaddressLocality"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:text="Address Locality" />
        <TextView
            android:id="@+id/tvName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
           android:text="Name" />
    
        <TextView
            android:id="@+id/tvAddress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Address" /></LinearLayout>
    
  2. 如下创建CustomAdapter类:

    import android.content.Context;    
    import android.support.annotation.NonNull;    
    import android.view.LayoutInflater;    
    import android.view.View;    
    import android.view.ViewGroup;    
    import android.widget.ArrayAdapter;    
    import android.widget.TextView;            
    import java.util.ArrayList;
    
    public class CustomLocationAdapter  extends ArrayAdapter<Location> {
    
        public CustomLocationAdapter(@NonNull Context context, ArrayList<Location> locations) {
            super(context,0, locations);
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // Get the data item for this position
            Location location = getItem(position);
            // Check if an existing view is being reused, otherwise inflate the view
            if (convertView == null) {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_location, parent, false);
            }
            // Lookup view for data population
            TextView tvAddressLocality = (TextView) convertView.findViewById(R.id.tvaddressLocality);
            TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
            TextView tvAddress = (TextView) convertView.findViewById(R.id.tvAddress);
            // Populate the data into the template view using the data object
            tvAddressLocality.setText(location.getAddressLocality());
            tvName.setText(location.getName());
            tvAddress.setText(location.getAddress());
            // Return the completed view to render on screen
            return convertView;
        }
    }
    
  3. 如下更新您的LocationAsyncTask

     public class LocationAsyncTask extends AsyncTask {
    
        private ArrayList<Location> locationList;
        private final WeakReference<ListView> listViewWeakReference;
    
        private Context context;
    
        public LocationAsyncTask(ListView listView, Context context) {
            this.listViewWeakReference = new WeakReference<>(listView);
            this.context = context;
        }
    
        @Override
        protected Object doInBackground(Object[] objects) {
            try {
                //These lines are an example(I will obtain the data via internet)
                Location ejemplo = new Location("Locality1s", "name", "address");
                Location ejemplo2 = new Location("Locality2", "name2", "address2");
                locationList = new ArrayList<Location>();
                locationList.add(ejemplo);
                locationList.add(ejemplo2);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            ArrayAdapter<Location> adapter = new CustomLocationAdapter(context, locationList);
            listViewWeakReference.get().setAdapter(adapter);
        }
    }
    
  4. 更新你LocationNativeActivity.onCreate()如下:

    ListView listView = LocationNativeActivity.this.findViewById(R.id.lvlocationnative);

    LocationAsyncTask myTask = new LocationAsyncTask(listView, this);

    myTask.execute();

【讨论】:

  • 谢谢!我更改了您的代码,现在可以正常工作。我在您的代码中删除了一个 },并通过 LocationNativeActivity 更改了 MainActivity,现在可以正常工作了。
  • @JavierC。没问题。谢谢指正!
【解决方案2】:

你可以替换你的代码:

LocationAsyncTask myTask = new LocationAsyncTask(this);

作为:

LocationAsyncTask myTask = new LocationAsyncTask(this){
            @Override
            protected void onPostExecute(Void aVoid) {
                  ListView s = (ListView)(findViewById(R.id.lvlocationnative));
                  ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(context, android.R.layout.simple_list_item_1, locationList);
                  s.setAdapter(adapter);  
            }
};

在您的异步任务中:

  • arrayList 设为公开
  • 使用这个onPostExecute() 方法:

    protected void onPostExecute(Void aVoid) {}
    

【讨论】:

  • 我需要在哪里写你的代码?在我活动的 onCreate() 中?谢谢
  • 我删除了 onPostExecute 方法并将上下文和数组列表变量更改为公共,但我在活动中的 @Override 行有问题。
  • 我没有说要删除 onpostExecute 方法。只需删除方法内的行。我也更新了
  • 现在我遇到了 onPostExecute 的 @Override 的问题:“方法不会覆盖其超类中的方法”
  • 能否请您发布您的代码,以便我检查一下
猜你喜欢
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 1970-01-01
  • 2013-10-28
  • 1970-01-01
相关资源
最近更新 更多