2015-09-28 73 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