2016-02-09 81 views
0

所以我在Android中有一個Sections Pager應用程序。在我的第四個片段中,我運行了一個通過藍牙連接到設備的asynctask,並更新了我創建的自定義列表(可能)。但是,列表要麼更新晚,要麼根本不更新。我不確定在postexecute上做什麼來允許更新,所以我更新了它在asynctask之外。在片段內的PostExecute中更新/創建自定義列表視圖

代碼如下:

 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. 
} 

任何幫助/評論/想法表示讚賞。

+0

更新列表的'AsyncTask'在哪裏? –

+1

我建議你遵循以大寫字母開頭的命名類的常規Java約定。 –

回答

1

中的代碼在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(); 
    } 
} 
+0

你好!感謝您的答覆!我的問題是我在onCreateView中創建自定義列表視圖。當asynctask完成時,視圖已經創建,所以我將不得不切換標籤以查看更新列表,但是到那時它已經運行了另一個asynctask,因此我運行了一個循環。有時它根本不會更新。我的問題與你的評論有關。我如何更新或在Postexecute上創建適配器? – Masterofawesome

+0

所以我不用再膨脹視圖了? – Masterofawesome

+0

我認爲最好保留對適配器的引用並更改數組列表,而不是在每次數據更改時創建新的適配器。 –

0

您只需更新titleList適配器中的ArrayList,並在適配器上調用notifyDataSetChanged()即可。我建議在titleList類中使用setList()方法做到這一點。您還需要將適配器的參考位置保存在您的AsyncTask可訪問的位置。

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(); 

    } 
} 
相關問題