2015-09-28 74 views
0

一些背景信息,第一隻在ListView中最後一項:安卓:顯示實施BaseAdapter

在我的Android應用程序,我在與一個物理按鍵SQLite數據庫的一些信息。這些信息包括髮布密鑰的'服務提供商'的名稱以及關鍵用途和該門的ID的描述。我試圖做的是在一個ListView元素的行中顯示每個'key'的所有信息,並在該行的末尾有一個刪除按鈕,可用於從數據庫中刪除該信息。

現在的問題是,當我試過這個活動中顯示的唯一條目是最後一個,其他條目將是空的空間。請參閱此處的屏幕截圖:(http://i.stack.imgur.com/8C15B.png

我用紅色標出的空間是前3個條目所在的空白區域。我已經看了這個問題,所有對這類問題的回答都是他們將數據輸入到數組列表中的問題,但我已經測試過了,並且ArrayList中正確填充了所有4個條目。我只是不知道他們爲什麼不顯示,我相對比較新的android,所以任何幫助將不勝感激!

這是來自相關文件的代碼: MainActivity.java :(完成我的調試打印語句這些打印語句都顯示在ArrayList的do while循環中添加4個不同的條目後addKeyItems()方法)

public class MainActivity extends AppCompatActivity { 

private ListView mKeyListView; 
//for the nav drawer 
private ListView mDrawerList; 
private ArrayAdapter<String> mAdapter; 
private ActionBarDrawerToggle mDrawerToggle; 
private DrawerLayout mDrawerLayout; 
private String mActivityTitle; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if(SaveSharedPreference.getUserName(MainActivity.this).length()==0){ 
     //log in 
     Intent intent = new Intent(this, LoginActivity.class); 
     startActivity(intent); 
     finish(); 
    }else{ 
     setContentView(R.layout.activity_main); 

     TextView textView = (TextView) findViewById(R.id.display_username); 
     String name = SaveSharedPreference.getUserName(this); 
     textView.setText("Logged in: " + name); 

     //navigation drawer 
     mDrawerList = (ListView)findViewById(R.id.navList); 
     System.out.println(mDrawerList); 
     addDrawerItems(); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     getSupportActionBar().setHomeButtonEnabled(true); 
     mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); 
     mActivityTitle = getTitle().toString(); 
     setupDrawer(); 

     //main content 
     mKeyListView = (ListView) findViewById(R.id.keyList); 
     addKeyItems(); 

    } 
} 
private void addKeyItems(){ 
    DbAccess dba = new DbAccess(); 
    Cursor cursor = dba.getKeys(getApplicationContext()); 
    if(cursor.moveToFirst()) { 

     List<KeyModel> myKeyModelList = new ArrayList<KeyModel>(); 
     int position = 0; 
     do { 
      KeyModel key = new KeyModel(); 
      key.setReaderId(cursor.getLong(cursor.getColumnIndexOrThrow(KeyReaderContract.KeyEntry._ID))); 
      key.setSpName(cursor.getString(cursor.getColumnIndexOrThrow(KeyReaderContract.KeyEntry.SP_NAME))); 
      key.setReaderDesc(cursor.getString(cursor.getColumnIndexOrThrow(KeyReaderContract.KeyEntry.READER_DESCRIPTION))); 
      myKeyModelList.add(key); 
      System.out.println(position+ " "+ key.getSpName()+ " "+ key.getReaderDesc()); 
      position++; 
     } while (cursor.moveToNext()); 

     for(int i = 0; i < myKeyModelList.size(); i++){ 
      KeyModel test = myKeyModelList.get(i); 
      System.out.println(test.spName+ " "+ test.readerDesc); 
     } 

     //create adapter with the arraylist of keys 
     MyListAdapter mKeyAdapter = new MyListAdapter(getLayoutInflater().inflate(R.layout.key_list_entry, (ViewGroup)findViewById(R.id.main_linear_layout))); 
     mKeyAdapter.setModel(myKeyModelList); 

     //set the adapter to the ListView 
     mKeyListView.setAdapter(mKeyAdapter); 

    } else{ 
     System.out.println("No keys"); 
    } 

} 

private class KeyModel{ 

    long readerId; 
    String spName; 
    String readerDesc; 

    public long getReaderId() { 
     return readerId; 
    } 

    public void setReaderId(long readerId) { 
     this.readerId = readerId; 
    } 

    public String getSpName() { 
     return spName; 
    } 

    public void setSpName(String spName) { 
     this.spName = spName; 
    } 

    public String getReaderDesc() { 
     return readerDesc; 
    } 

    public void setReaderDesc(String readerDesc) { 
     this.readerDesc = readerDesc; 
    } 

    View.OnClickListener listener = new View.OnClickListener(){ 

     @Override 
     public void onClick(View v) { 
      Toast.makeText(MainActivity.this, spName, Toast.LENGTH_SHORT).show(); 
      //do other things to delete this once all items are displaying correctly 
     } 
    }; 
} 

private class MyListAdapter extends BaseAdapter{ 
    View renderer; 
    List<KeyModel> keys; 
    // call this one and pass it layoutInflater.inflate(R.layout.key_list_entry) 
    public MyListAdapter(View renderer) { 
     this.renderer = renderer; 
    } 

    // whenever you need to set the list of keys just use this method. 
    // call it when you have the data ready and want to display it 
    public void setModel(List<KeyModel> keys){ 
     this.keys = keys; 
     System.out.println(keys.size()); 
     notifyDataSetChanged(); 
    } 

    @Override 
    public int getCount() { 
     if(keys!=null){ 
      return keys.size(); 
     } 
     return 0; 
    } 
    @Override 
    public Object getItem(int position) { 
     if(keys!=null){ 
      return keys.get(position); 
     } 
     return null; 
    } 
    @Override 
    public long getItemId(int position) { 

     if(keys!=null){ 
      System.out.println("item id "+ position); 
      return position; 
     } 
     System.out.println(-1); 
     return -1; 
    } 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if(convertView==null){ 
      convertView = renderer; 
     } 
     KeyModel key = keys.get(position); 
     System.out.println(position+ " "+ key.getSpName()+ " "+ key.getReaderDesc()); 

     TextView rIdView = (TextView)convertView.findViewById(R.id.key_id); 
     rIdView.setText(Long.toString(key.readerId)); 

     TextView spNameView = (TextView)convertView.findViewById(R.id.sp_name); 
     spNameView.setText(key.spName); 

     TextView readerDescView = (TextView)convertView.findViewById(R.id.reader_desc); 
     readerDescView.setText(key.readerDesc); 

     Button button = (Button)convertView.findViewById(R.id.delete_keyButton); 
     button.setOnClickListener(key.listener); 
     convertView.setVisibility(View.VISIBLE); 
     return convertView; 
    } 
} 

activity_main.xml中:

<android.support.v4.widget.DrawerLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/drawer_layout" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<!-- The first child in the layout is for the main Activity UI--> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:id="@+id/main_list_layout"> 
    <TextView 
     android:id="@+id/display_username" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 
    <ListView xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:id="@+id/keyList" 
     android:orientation="vertical" > 
    </ListView> 
</LinearLayout> 
<!-- Side navigation drawer UI --> 
<ListView 
    android:id="@+id/navList" 
    android:layout_width="200dp" 
    android:layout_height="match_parent" 
    android:layout_gravity="start" 
    android:background="#424242"/> 

key_list_entry.xml :

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="horizontal" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:id="@+id/main_linear_layout"> 

<RelativeLayout 
    android:layout_width="0dip" 
    android:layout_height="fill_parent" 
    android:layout_weight="0.05"> 
    <TextView 
     android:id="@+id/key_id" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
</RelativeLayout> 

<RelativeLayout 
    android:layout_width="0dip" 
    android:layout_height="fill_parent" 
    android:layout_weight="0.35"> 
    <TextView 
     android:id="@+id/sp_name" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
</RelativeLayout> 

<RelativeLayout 
    android:layout_width="0dip" 
    android:layout_height="fill_parent" 
    android:layout_weight="0.35"> 
    <TextView 
     android:id="@+id/reader_desc" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"/> 
</RelativeLayout> 
<RelativeLayout 
    android:layout_width="0dip" 
    android:layout_height="fill_parent" 
    android:layout_weight="0.25"> 
    <Button 
     android:id="@+id/delete_keyButton" style="?android:textAppearanceSmall" 
     android:layout_width="wrap_content" android:layout_height="wrap_content" 
     android:text="@string/delete" android:textStyle="bold" /> 
</RelativeLayout> 

在MyListAdapter的GetView方法打印語句:System.out.println(position+ " "+ key.getSpName()+ " "+ key.getReaderDesc()); 它輸出中的每個列表中的4種元素的正確作爲方法被稱爲:

這裏是輸出中:

09-28 20:23:47.731 20156-20156/com.blah.blah I/System.out﹕ 0 Company1 Front door 
09-28 20:23:47.745 20156-20156/com.blah.blah I/System.out﹕ 1 Company1 Back Door 
09-28 20:23:47.745 20156-20156/com.blah.blah I/System.out﹕ 2 Occipitech Front door 
09-28 20:23:47.746 20156-20156/com.blah.blah I/System.out﹕ 3 Occipitech Garage door 

再次,任何幫助,將不勝感激!這是我的第一篇文章,讓我知道如果我做錯了什麼,或者你需要更多的信息。我認爲這個問題可能在我的BaseAdapter實現中,因爲列表本身具有所有正確的信息。

+0

好像你不明白適配器的概念在所有...所以這將是很難解釋......但現在基本上您對所有項目視圖都使用**相同的視圖**我無法相信它不會拋出像*視圖已經有父項的異常* ...適配器的概念。getView'提供新項目或重用'convertView' – Selvin

+0

不使用'BaseAdapter',使用'SimpleCursorAdapter'代替 – pskink

+0

謝謝@Selvin和pskink我認爲我現在對它更瞭解了。我感謝您的意見! :) – Caro

回答

0

不得在所有列表項中使用單個視圖。列表中顯示的所有行必須是唯一的視圖,它們會根據傳遞的數據進行回收。

所以改變..

if(convertView==null){ 
     convertView = renderer; 
} 

if(convertView==null){ 
    LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 
    convertView = inflater.inflate(R.layout.key_list_entry); 
} 
+0

完美的做到了。我很清楚它是如何解決這個問題的:我之前做的工作是將充氣的視圖傳遞給我的適配器的構造函數到'renderer'變量中,並且每次都在getView中使用相同的視圖,但基本上覆蓋它。現在使用此修復程序,它爲列表中的每一行創建一個新視圖。那是對的嗎?感謝您的幫助:)我已經提高了您的答案,但我沒有足夠的積分來顯示。再次感謝! – Caro