2012-03-14 120 views
1

我想構建由ArrayAdapter支持的多行ListView。我希望列表中的每一行都有兩行,並在其旁邊有一個刪除按鈕。當點擊刪除按鈕時,應該刪除數組中的項目,並且ListView應該自行刷新。Android - 使用自定義ArrayAdapter添加和刪除多行ListView中的項目

這是在MainActivity的代碼,它有一個內部類是定製ArrayAdapter:

public class MainActivity extends Activity { 
ArrayList<String> artistsList = new ArrayList<String>(); 
String[] artists = {"Matt Nathanson", "Green Day", "Three Days Grace", "LMFAO", "One Direction", 
     "Linkin Park", "Neon Trees", "Cee Lo Green", "Plain White T's", "Metallica", "Maroon 5", 
     "Sick Puppies", "Bruno Mars", "Billy Joel", "Don McLean", "Adele", "Gary Jules"}; 
ArrayList<String> songsList = new ArrayList<String>(); 
String[] songs = {"Come On Get Higher", "Holiday", "I Hate Everything About You", "Sexy and I Know It", "What Makes You Beautiful", 
     "What I've Done", "Animal", "Fuck You", "Hey There Delilah", "Sandman", "Moves Like Jagger", 
     "Rip Tide", "Talking to the Moon", "Piano Man", "American Pie", "Someone Like You", "Mad World"}; 

ListView list; 
TestArrayAdapter mArrayAdapter; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    for(String s : artists) { 
     artistsList.add(s); 
    } 
    for(String s : songs) { 
     songsList.add(s); 
    } 

    mArrayAdapter = new TestArrayAdapter(); 

    list = (ListView)findViewById(R.id.mainlist); 

    list.setAdapter(mArrayAdapter); 
} 


class TestArrayAdapter extends ArrayAdapter<String> { 

    public TestArrayAdapter() { 
     super(MainActivity.this, R.layout.row, songs); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     LayoutInflater inflater = getLayoutInflater(); 
     View row=inflater.inflate(R.layout.row, parent, false); 

     TextView primaryTextView = (TextView)row.findViewById(R.id.primaryTextView); 
     TextView secondaryTextView = (TextView)row.findViewById(R.id.secondaryTextView); 

     primaryTextView.setText(songsList.get(position)); 
     secondaryTextView.setText(artistsList.get(position)); 

     ImageView deleteButton = (ImageView)row.findViewById(R.id.deleteRowButton); 
     deleteButton.setTag(position); 
     deleteButton.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       artistsList.remove(v.getTag()); 
       songsList.remove(v.getTag()); 
       mArrayAdapter.notifyDataSetChanged(); 
      } 
     }); 

     return row; 
    } 
} 

調用notifyDataSetChanged()似乎並沒有做任何事情;但是,ArrayList中的項目正在被刪除。 ListView似乎獨立於我在ArrayLists和ArrayAdapter中所做的更改。理想情況下,當我從底層數據中刪除一個項目時,我應該能夠調用notifyDataSetChanged(),並且ListView將自行更新。

我已經看過類似的其他問題,但他們都只有一個ArrayList提供數據到ListView,我不知道如何適應這些解決方案的多行行。提前致謝。

回答

1

我最近寫了一篇關於如何創建類似listview的教程。看看這裏

http://www.shubhayu.com/android/listview-with-arrayadapter-and-customized-items

這將幫助你創建你想除了刪除部分內容。此後刪除將不會很困難。你只需要在你的刪除按鈕的onClick上處理它。一旦你列出並運行清單,我會指導你完成。

此外,重寫你的getCount()。這應該夠了吧。

+0

非常感謝!本教程非常有幫助。我知道它刪除的項目。 – Cybran 2012-03-14 22:05:43

0

這對我有效,我建議你使用它。您使用兩個字符串來維護數據,創建一個類並使用該類創建arrayadapter。我正在發佈一個來自我當前(不完整)代碼的示例。

我使用自定義ArrayAdapter作爲單例,並通過實例對其進行修改。我還有一個服務正在運行,在事件Android將內存中的單例破壞的情況下維護數據的備份。每次我做一個notifydatasetchanged,我在該服務中的一個公共靜態變量中備份規則。你可以忽略這部分,因爲它只有我的情況需要。

public class RuleManager extends ArrayAdapter<Rule> 
{ 
    private static RuleManager mInstance; 
    private final Context context; 

    private RuleManager(Context context, List<Rule> r) 
    { 
    super(context,R.layout.main_menu_options_list_item); 
    if(r==null)r=new ArrayList<Rule>(); 
    this.context=context; 
    } 
    public static synchronized RuleManager getInstance(Context context,List<Rule> r) 
    { 
     if (mInstance == null) 
     { 
      if(r==null) 
       r=CallMonitor.ruleBackup; //A service that contains copy of entire data (as a backup if android destroys stuffs) 
      mInstance = new RuleManager(context, r); 
     } 
     return mInstance; 
    }  

    public void addRule(Rule rule) 
    { 
     add(rule); 
     notifyDataSetChanged(); 
     backupRules(); 
    } 
    private void backupRules() 
    { 
     CallMonitor.ruleBackup=null; 
     CallMonitor.ruleBackup=new ArrayList<Rule>(); 
     for(int i=0;i<getCount();i++) 
      CallMonitor.ruleBackup.add(getItem(i)); 
    } 
    public void editRule(int position,Rule rule) 
    { 

     getItem(position).setAbc(rule.getAbc); 
     getItem(position).setDef(rule.getDef()); 
     getItem(position).setGhi(rule.getGhi()); 
     getItem(position).setJkl(rule.getJkl()); 
     notifyDataSetChanged(); 
     backupRules(); 

    } 
    public boolean deleteRule(int position) 
    { 
     try 
     { 
      remove(getItem(position)); 
      notifyDataSetChanged(); 
      backupRules(); 
      return true; 
     } 
     catch(Exception e) 
     { 
      return false; 
     }  
    } 
} 
0
super(MainActivity.this, R.layout.row, songs); 

爲什麼你有這樣的傳球songs列表中選擇適配器構造函數。

我不確定,因爲我還沒有實現與多個數據資源(在你的情況下2列表)的列表視圖。

但是,理想的做法是創建一個新類(在你的情況下它只有兩個字符串:歌曲,藝術家)。 Single該類的對象表示列表視圖中的單行信息。因此將它傳遞給您的自定義適配器,並在getView()中使用來自該類對象的數據進行列表視圖。

在你的情況,notifydatasetchanged()可能無法工作,因爲你已經設置songs是在適配器的構造函數的objects to represent in the ListView,因此不千變萬化......因此列表不刷新在所有...

相關問題