在片段内的PostExecute上更新/创建自定义列表视图

时间:2016-02-09 18:32:50

标签: android android-fragments android-asynctask bluetooth

所以我在Android中有一个Sections寻呼机应用程序。在我的第四个片段中,我运行一个asynctask,通过蓝牙连接到设备并更新我创建的自定义列表(据说)但是,列表要么迟到更新要么根本不更新。我不确定如何在postexecute上做什么来允许更新,所以我在asynctask之外更新了它。

代码如下:

     public class FourthFragment extends Fragment {
    private WeakReference<getBeacons> getBeaconTaskWeakRef;
    ArrayList<ArtInfo> ArtList = new ArrayList<>();
    ;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        startNewBeaconsAsyncTask();
    }

    ArrayList<String> titles = new ArrayList<>();
    ArrayList<String> artists = new ArrayList<>();
    ArrayList<String> years = new ArrayList<>();
    ArrayList<Integer> images = new ArrayList<>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        for (int i = 0; i < ArtList.size(); i++) {
            titles.add(ArtList.get(i).getArtTitle());
            artists.add(ArtList.get(i).getArtistName());
            years.add(ArtList.get(i).getYear());
            int resID = getResources().getIdentifier(ArtList.get(i).getImageFilename(), "drawable", "com.acuart.acumen.acuart");
            images.add(resID);
        }
        View v = inflater.inflate(R.layout.frag_list, container, false);
        ListView byTitleList = (ListView) v.findViewById(R.id.byTitleList);
        byTitleList.setAdapter(new titleList(getActivity(), R.layout.custom_list, titles));
        return v;
    }

    private void startNewBeaconsAsyncTask() {
        getBeacons newbeacons = new getBeacons(this);
        this.getBeaconTaskWeakRef = new WeakReference<getBeacons>(newbeacons);
        newbeacons.execute();
    }

    class titleList extends ArrayAdapter<String> {
        public titleList(Context context, int resource, ArrayList<String> objects) {
            super(context, resource, objects);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = ((Activity) getContext()).getLayoutInflater().inflate(R.layout.custom_list, null);
            TextView title = (TextView) v.findViewById(R.id.row_title);
            TextView artist = (TextView) v.findViewById(R.id.row_artist);
            TextView year = (TextView) v.findViewById(R.id.row_year);
            ImageView image = (ImageView) v.findViewById(R.id.row_image);

            title.setText(titles.get(position));
            artist.setText(artists.get(position));
            year.setText(years.get(position));
            image.setBackgroundResource(images.get(position));
            return v;
        }
    }

    private class getBeacons extends AsyncTask<Void, Void, Void> {
        private WeakReference<FourthFragment> fragmentWeakReference;

        private getBeacons(FourthFragment fragment) {
            this.fragmentWeakReference = new WeakReference<FourthFragment>(fragment);
        }

        ProgressDialog dialog = new ProgressDialog(getActivity());
        Context context = getApplicationContext();
        int artCount = 0;
        SQLHelper markerDBHelper = new SQLHelper(context);

        @Override
        protected void onPreExecute() {
            dialog.setMessage("Loading, please wait...");
            dialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            checkBluetooth();
        }

        @Override
        protected void onPostExecute(Void v) {
            dialog.dismiss();
        }
    }       //processing bluetooth data and creating a query for database return.
}

感谢任何帮助/意见/想法。

3 个答案:

答案 0 :(得分:1)

onPostExecute()中的代码在UI线程上运行,因此您应该能够在那里更新列表适配器。

我对你的问题感到有点困惑,你是说onPostExecute()运行需要很长时间吗?您是否有代码在那里更新列表,然后将其移出,因为onPostExecute()花了太长时间才被调用?

你有其他一些异步任务在运行吗?

我没有时间测试编译/测试这个,所以很可能会出现一些语法错误,但这只是为了给你一个想法

titleList中添加一个方法来更新支持适配器列表的数据,所以:

public void updateAdapterData(ArrayList<String> newData) {
    clear();
    addAll(newData);
    notifyDataSetChanged();
}

异步任务可以做这样的事情

private titleList mTitleList; //Set this in your onCreateView

private class getBeacons extends AsyncTask<Void, Void, ArrayList<String>> {

    @Override
    protected void onPreExecute() {
        dialog.setMessage("Loading, please wait...");
        dialog.show();
    }

    @Override
    protected ArrayList<Object> doInBackground(Void... params) {
        //If checkbluetooth returns a list..
        return checkBluetooth();
    }

    @Override
    protected void onPostExecute(ArrayList<String> newList) {
        mTitleList.updateAdapterData(newList)
        dialog.dismiss();
    }
}

答案 1 :(得分:1)

首先按如下方式设置ListView适配器:

titleList adapter=new titleList(getActivity(), R.layout.custom_list, titles));
byTitleList.setAdapter(adapter);

在执行后台任务后,如果您获得“标题”列表,则在“onPostExecute”方法中,您可以执行以下操作: -

private class getBeacons extends AsyncTask<Void, Void, ArrayList<String> > {

    ArrayList<String> titles = new ArrayList<String>();

    private getBeacons() {

    }



    @Override
    protected void onPreExecute() {

    }

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

        //call a method for assigning values to titles
        return titles;

    }

    @Override
    protected void onPostExecute(ArrayList<String> titles) {

        //Now assign this arraylist referrence to your actual titles arraylist 

        adapter.notifyDataSetChanged();

    }
}  

答案 2 :(得分:0)

您只需更新ArrayList适配器中的titleList并在适配器上调用notifyDataSetChanged()即可。我建议在setList()类中使用titleList方法执行此操作。您还需要保留AsyncTask可以访问的适配器的引用。