【问题标题】:How to customize an adapter in Android?如何在 Android 中自定义适配器?
【发布时间】:2015-11-01 17:06:34
【问题描述】:

我正在制作一个简单的 Android 应用,它获取用户的姓名、电子邮件和联系电话,并将这些(包括 ID)保存在手机的内存中(通过 sqlite)。 “显示全部”页面使用自定义适配器在 ListView 中显示数据库中所有用户的详细信息。它是这样运行的:

它将这些空格留在行之间。如何删除这些空格? 此外,在从数据库中检索时,细节会混淆。就像第一行以正确的格式显示(如我所愿)。但第二个细节搞混了。我该如何纠正这个问题?

MyDBHandler.java

public class MyDBHandler extends SQLiteOpenHelper{

    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME= "user.db";
    public static final String TABLE_NAME = "data";
    public static final String COLUMN_ID = "id";
    public static final String COLUMN_NAME = "name";
    public static final String COLUMN_email = "email";
    public static final String COLUMN_phno = "phno";

    public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        String query = "CREATE TABLE "+TABLE_NAME+"("+
                COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"+
                COLUMN_NAME + " VARCHAR(20),"+
                COLUMN_email + " VARCHAR(20),"+
                COLUMN_phno + " VARCHAR(20)"+
                ");";

        db.execSQL(query);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {


        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

    public void addData(Data d){
        ContentValues values = new ContentValues();
        //values.put(COLUMN_ID, d.getId());
        values.put(COLUMN_NAME, d.getName());
        values.put(COLUMN_email, d.getEmail());
        values.put(COLUMN_phno, d.getPhno());

        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_NAME, null, values);
        db.close();
    }

    public ArrayList<String> retrieveData(){

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

        SQLiteDatabase db = getWritableDatabase();
        String query = "SELECT * FROM "+TABLE_NAME+";";

        Cursor c = db.rawQuery(query,null);

        c.moveToFirst();

        while(!c.isAfterLast()){
            if(c.getString(c.getColumnIndex("id"))!=null){

                al.add(c.getString(c.getColumnIndex("id")));
                al.add(c.getString(c.getColumnIndex("name")));
                al.add(c.getString(c.getColumnIndex("email")));
                al.add(c.getString(c.getColumnIndex("phno")));

            }
            c.moveToNext();
        }
        db.close();
        return al;

    }

}

CustomAdapter.java

public class CustomAdapter extends ArrayAdapter<String>{


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


    public CustomAdapter(Context context,   ArrayList<String>a ){
        super(context,R.layout.custom_row,a);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater harshitsInflator = LayoutInflater.from(getContext());
        View customView = harshitsInflator.inflate(R.layout.custom_row, parent, false);

        TextView textView3 = (TextView) customView.findViewById(R.id.textView3);
        TextView textView4 = (TextView) customView.findViewById(R.id.textView4);
        TextView textView5 = (TextView) customView.findViewById(R.id.textView5);
        Button button4 = (Button) customView.findViewById(R.id.button4);

        String Sid = getItem(position);

        if(position%4==0 && position>0)
        {
            textView3.setText(a.get(1));
            textView4.setText(a.get(2));
            textView5.setText(a.get(3));
            button4.setText(a.get(0));
            a.clear();
            customView.setVisibility(View.VISIBLE);
        }
        else {
            a.add(Sid);
            customView.setVisibility(View.GONE);
        }
        return customView;
    }
}

listView.java

public class listView extends Activity {

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_view_layout);

        ArrayList<String> n;


        MyDBHandler db = new MyDBHandler(this, null, null, 1);

        n=db.retrieveData();

        ListAdapter harshitsAdapter = new CustomAdapter(this, n);

        ListView harshitsListView = (ListView) findViewById(R.id.harshitsListView);
        harshitsListView.setAdapter(harshitsAdapter);
        //((BaseAdapter)harshitsAdapter).notifyDataSetChanged();




    }

    public void backToMain(View view){

        Intent i = new Intent(this, MainActivity.class);
        startActivity(i);
        finish();
    }
}

此应用还显示ArrayIndexOutOfBounds 异常:

Process: com.example.h8pathak.dilliheart, PID: 21258
    java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
            at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
            at java.util.ArrayList.get(ArrayList.java:308)

我该如何纠正这个问题?

【问题讨论】:

  • 使用列表的长度来检查越界,这样你就不会遇到这种异常
  • 尝试使用@StanlyMoses 提到的长度,或者为什么不编写自己的 RecyclerViewAdapter 呢?
  • 我看不到数组列表a 的用途。如果该列表还存储您的数据,那么您将在 getView() 期间清除它。您无法修改用于显示您的视图的数据。
  • 为什么不能使用 CursorAdapter 来代替?

标签: java android sqlite listview custom-adapter


【解决方案1】:

修改你的这两个文件:

CustomAdapter.java

public class CustomAdapter extends ArrayAdapter<String>{

    ArrayList<String> id, name, email, phno;
    Context c;


    public CustomAdapter(Context context,   ArrayList<String>id, ArrayList<String>name , ArrayList<String>email , ArrayList<String> phno ){
        super(context,R.layout.custom_row, id);

        this.c=context;
        this.id = id;
        this.name=name;
        this.email=email;
        this.phno=phno;

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater harshitsInflator = LayoutInflater.from(getContext());
        View customView = harshitsInflator.inflate(R.layout.custom_row, parent, false);

        TextView textView3 = (TextView) customView.findViewById(R.id.textView3);
        TextView textView4 = (TextView) customView.findViewById(R.id.textView4);
        TextView textView5 = (TextView) customView.findViewById(R.id.textView5);
        Button button4 = (Button) customView.findViewById(R.id.button4);


            String Sid = id.get(position);
            String Sname = name.get(position );
            String Semail = email.get(position );
            String Sphno = phno.get(position);

            textView3.setText(Sname);
            textView4.setText(Semail);
            textView5.setText(Sphno);
            button4.setText(Sid);

        return customView;
    }
}

listView.java

public class listView extends Activity {

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_view_layout);

        ArrayList<String> n;
        ArrayList<String> id  = new ArrayList<>();
        ArrayList<String> name  = new ArrayList<>();
        ArrayList<String> email  = new ArrayList<>();
        ArrayList<String> phno  = new ArrayList<>();

        MyDBHandler db = new MyDBHandler(this, null, null, 1);

        n=db.retrieveData();

        for(int i =0; i<n.size();i++){
            if(i%4==0)
                id.add(n.get(i));
            else if (i%4==1)
                name.add(n.get(i));
            else if (i%4==2)
                email.add(n.get(i));
            else
                phno.add(n.get(i));
        }

        System.out.println(n);


        ListAdapter harshitsAdapter = new CustomAdapter(this, id, name, email, phno);

        ListView harshitsListView = (ListView) findViewById(R.id.harshitsListView);
        harshitsListView.setAdapter(harshitsAdapter);




    }

    public void backToMain(View view){

        Intent i = new Intent(this, MainActivity.class);
        startActivity(i);
        finish();
    }





}

调整此方法也不会导致“ArrayIndexOutOfBounds”异常

【讨论】:

    【解决方案2】:

    好的,将所有数据存储在模型类 Data 中,并将 Data 对象添加到 ListView。更改您的数据库方法以获取所有这样的数据

    public ArrayList<Data> retrieveData(){
    
            ArrayList<Data> al = new ArrayList<>();
    
            SQLiteDatabase db = getWritableDatabase();
            String query = "SELECT * FROM "+TABLE_NAME+";";
    
            Cursor c = db.rawQuery(query,null);
    
            c.moveToFirst();
    
            while(!c.isAfterLast()){
                if(c.getString(c.getColumnIndex("id"))!=null){
    
                    Data dt = new Data();
                    dt.setId(c.getString(c.getColumnIndex("id")));
                    dt.setName(c.getString(c.getColumnIndex("name")));
                    dt.setEmail(c.getString(c.getColumnIndex("email")));
                    dt.setPhno(c.getString(c.getColumnIndex("phno")));
    
                    al.add(dt);
    
                }
                c.moveToNext();
            }
            db.close();
            return al;
    
        }
    

    使用 getter 方法检索数据。希望对你有用。

    【讨论】:

      【解决方案3】:

      首先,我应该创建一个值对象来使用。例如:

      public class UserVO {
      
          private long id;
          private String name,
                         email, 
                         contactNumber;
      
          public long getId() {
              return id;
          }
      
          public void setId(long id) {
              this.id = id;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public String getEmail() {
              return email;
          }
      
          public void setEmail(String email) {
              this.email = email;
          }
      
          public String getContactNumber() {
              return contactNumber;
          }
      
          public void setContactNumber(String contactNumber) {
              this.contactNumber = contactNumber;
          }
      
      }
      

      然后你可以像下面这样在你的类中使用它:

      public class CustomAdapter extends ArrayAdapter<UserVO>{
      
          private UserVO mUser;
          private Context mContext;
          private LayoutInflater mLayoutInflater;
          private ViewHolder mHolder;
      
          public CustomAdapter(Context context, UserVO user){
      
              mContext = context;
              mUser = user;
      
          }
      
          static class ViewHolder {
      
              private TextView textView3,
                               textView4,
                               textView5;
      
          }
      
          @Override
          public View getView(int position, View view, ViewGroup parent) {
      
              if (view == null) {
      
                  view = layoutInflater.inflate(R.layout.custom_row, parent, false);
      
                  mHolder = new ViewHolder();
      
                  mHolder.textView3 = (TextView) view.findViewById(R.id.textView3);
                  mHolder.textView4 = (TextView) view.findViewById(R.id.textView4);
                  mHolder.textView5 = (TextView) view.findViewById(R.id.textView5);
      
                  view.setTag(mHolder);
      
              }
              else {
      
                  mHolder = (ViewHolder) view.getTag();
      
              }
      
              mUser = getItem(position);
      
              mHolder.textView3.setText(mUser.getId());
              mHolder.textView4.setText(mUser.getEmail());
              mHolder.textView5.setText(mUser.getContactNumber());
      
              return view;
          }
      
      }
      

      在您的MyDBHandler 中,您无需将光标移动到第一个位置。那可能是你说的异常错误。此外,您还可以返回用户列表,例如:

      public ArrayList<UserVO> retrieveData(){
      
          ArrayList<UserVO> userList = new ArrayList<>();
      
          SQLiteDatabase db = getWritableDatabase();
          String query = "SELECT * FROM " + TABLE_NAME + ";";
      
          Cursor c = db.rawQuery(query, null);
      
          while(c.moveToNext()) {
      
              if(c.getString(c.getColumnIndex("id")) != null) {
      
                  UserVO _user = new UserVO();
      
                  _user.setId(c.getLong(c.getColumnIndex("id")));
                  _user.setName(c.getString(c.getColumnIndex("name")));
                  _user.setEmail(c.getString(c.getColumnIndex("email")));
                  _user.setContactNumber(c.getString(c.getColumnIndex("phno")));
      
                  userList.add(_user);
      
              } 
      
          }
      
          db.close();
      
          return userList;
      
      }
      

      最后你可以加载你的ListView

      public class listView extends Activity {
      
          protected void onCreate(Bundle savedInstanceState){
              super.onCreate(savedInstanceState);
              setContentView(R.layout.list_view_layout);
      
              ArrayList<UserVO> userList;
      
      
              MyDBHandler db = new MyDBHandler(this, null, null, 1);
      
              userList = db.retrieveData();
      
              ListAdapter harshitsAdapter = new CustomAdapter(this, userList);
      
              ListView harshitsListView = (ListView) findViewById(R.id.harshitsListView);
      
              harshitsListView.setAdapter(harshitsAdapter);
      
          }
      
          public void backToMain(View view){
      
              Intent i = new Intent(this, MainActivity.class);
              startActivity(i);
              finish();
          }
      
      }
      

      这些类只是示例。你必须编辑一些东西才能让它工作,诅咒。不管怎样,你想问什么都可以。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-31
        • 2021-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多