2012-04-27 130 views
3

我正在努力將我的列表視圖行分配多個文本視圖。 我希望我的行有一個人名的文本視圖,一個用於地址,一個用於年齡 - 但我沒有成功。Android自定義列表視圖行

如果有人能爲我提供一個簡單的例子,那就太好了。

謝謝!

這裏是我的自定義ArrayAdapter

import java.util.ArrayList; 

import android.content.Context; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.TextView; 

public class MyAdapter extends BaseAdapter { 
    private LayoutInflater mInflater = null; 
    private ArrayList<Invoice> peopleList; 

    private final class ViewHolder { 
     TextView kidLabel; 
     TextView restLabel; 
     TextView fristLabel; 
     TextView amountLabel; 
    } 

    private ViewHolder mHolder = null; 

    public MyAdapter(Context context) { 
     Context mContext = context; 
     mInflater = (LayoutInflater) mContext 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public int getCount() { 
     return peopleList.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return position; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if (convertView == null) { 
      mHolder = new ViewHolder(); 
      convertView = mInflater.inflate(R.layout.row, null); 
      convertView.setTag(mHolder); 
     } else { 
      mHolder = (ViewHolder) convertView.getTag(); 
     } 

     mHolder.kidLabel = (TextView) convertView.findViewById(R.id.kidLabel); 
     mHolder.kidLabel.setText(peopleList.get(position).getKID()); 

     mHolder.fristLabel = (TextView) convertView 
       .findViewById(R.id.fristLabel); 
     mHolder.fristLabel.setText(peopleList.get(position).getDueDate()); 

     mHolder.restLabel = (TextView) convertView.findViewById(R.id.restLabel); 
     mHolder.restLabel.setText(peopleList.get(position).getDueAmount()); 

     mHolder.amountLabel = (TextView) convertView 
       .findViewById(R.id.amountLabel); 
     mHolder.amountLabel.setText(peopleList.get(position).getDueAmount()); 

     return convertView; 
    } 
} 

,這裏是我的自定義行的xml:

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

    <ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="fill_parent" 
     android:layout_height="45dip" 
     android:src="@drawable/cellback" android:scaleType="fitXY"/> 

    <TextView 
     android:id="@+id/kidLabel" 
     android:layout_width="160dip" 
     android:layout_height="25dip" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:textSize="13dip" android:textColor="#333"/> 

    <TextView 
     android:id="@+id/fristLabel" 
     android:layout_width="160dip" 
     android:layout_height="20dip" 
     android:layout_marginTop="25dip" 
     android:textSize="11dip" android:textColor="#999"/> 

    <TextView 
     android:id="@+id/amountLabel" 
     android:layout_width="160dip" 
     android:layout_height="25dip" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:textSize="13dip" android:layout_marginLeft="160dip" android:gravity="right" android:textColor="#333"/> 

    <TextView 
     android:id="@+id/restLabel" 
     android:layout_width="160dip" 
     android:layout_height="20dip" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:textSize="11dip" android:layout_marginLeft="160dip" android:layout_marginTop="25dip" android:gravity="right" android:textColor="#999"/> 

</RelativeLayout> 
+0

給我們看一些代碼。你有什麼嘗試? – Th0rndike 2012-04-27 07:19:06

+3

有很多很多重複的,嘗試'listview自定義佈局'的第一個命中是SO:http://stackoverflow.com/questions/5649872/listview-custom-layout – Bondax 2012-04-27 07:19:20

回答

9

首先,你應該創建一個XML來描述你的列表細胞喜歡什麼,叫cell.xml,例如:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" android:background="@color/spink"> 

    <TextView 
     android:id="@+id/name_textView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Name" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

    <TextView 
     android:id="@+id/address_textView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Address" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 

</LinearLayout> 

二,創建adapter.It幫助你的列表視圖來顯示數據:

public class MyAdapter extends BaseAdapter { 
private LayoutInflater mInflater = null; 
private ArrayList<People> peopleList; 

private final class ViewHolder { 
TextView nameTextView; 
TextView addressTextView; 
} 

private ViewHolder mHolder = null; 

public MyAdapter(Context context) { 
mContext = context; 
mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

@Override 
public int getCount() { 
return peopleList.size(); 
} 

@Override 
public Object getItem(int position) { 
return position; 
} 
@Override 
public long getItemId(int position) { 
return position; 
} 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
if(convertView == null) { 
mHolder = new ViewHolder(); 
convertView = mInflater.inflate(R.layout.cell, null);   
convertView.setTag(mHolder); 
} else { 
mHolder = (ViewHolder)convertView.getTag(); 
} 

mHolder.nameTextView (TextView)convertView.findViewById(R.id.name_textView); 
mHolder.nameTextView.setText(peopleList.get(position).getName()); 
mHolder.addressTextView = (TextView)convertView.findViewById(R.id.address_textView); 
mHolder.addressTextView.setText(peopleList.get(position).getAddress()); 

return convertView; 
} 
} 

最後,當您要顯示數據時,請在您的活動中執行以下操作:

listView.setAdapter(new MyAdapter());

希望它可以幫助你。

+0

謝謝!我傾向於這個anser,但是當我嘗試將適配器分配給listView像這樣: ListView infoTable =(ListView)this.findViewById(R.id.list); \t \t MyAdapter ad = new MyAdapter(getBaseContext()); \t \t infoTable.setAdapter(ad); 該應用程序崩潰,沒有明確的錯誤信息... – PinkFloydRocks 2012-04-27 10:52:44

+0

原來這是peoplelist是空的應用程序崩潰。所以這個答案。謝謝! – PinkFloydRocks 2012-04-27 11:09:50

2

你需要創建一個自定義列表視圖佈局和自定義陣列適配器(我還創建了一個自定義類與佈局一起工作)。

這方面的一個例子是:

自定義類,它使用自定義列表視圖佈局工程:

package id10778734.sceresini.week4.exercise3.views; 

import id10778734.sceresini.week4.exercise3.R; 
import id10778734.sceresini.week4.exercise3.Constants; 
import id10778734.sceresini.week4.exercise3.tasks.Task; 
import android.content.Context; 
import android.util.AttributeSet; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

public class TaskListItem extends LinearLayout { 
    private Task mTask; 
    private ImageView mEmailImageView; 
    private ImageView mPriorityImageView; 
    private TextView mTaskNameTextView; 
    private TextView mTaskResponsibleTextView; 
    private ImageView mDeleteImageView; 

    public TaskListItem (Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public void onFinishInflate() { 
     super.onFinishInflate(); 
     mEmailImageView = (ImageView) findViewById(R.id.list_row_layout_email_button); 
     mPriorityImageView = (ImageView) findViewById(R.id.list_row_layout_priority_icon); 
     mTaskNameTextView = (TextView) findViewById(R.id.list_row_layout_task_name); 
     mTaskResponsibleTextView = (TextView) findViewById(R.id.list_row_layout_responsible); 
     mDeleteImageView = (ImageView) findViewById(R.id.list_row_layout_delete_button); 

    } 

    public void setTask (Task task) { 
     mTask = task; 
     mEmailImageView.setTag(task); 

     switch (task.getPriority()) { 
     case Constants.LOW: 
          mPriorityImageView.setImageResource(R.drawable.low); 
          break; 
     case Constants.MEDIUM: 
          mPriorityImageView.setImageResource(R.drawable.medium); 
          break; 
     case Constants.HIGH: 
          mPriorityImageView.setImageResource(R.drawable.high); 
          break; 
     } 

     mTaskNameTextView.setText(task.getName()); 
     mTaskResponsibleTextView.setText(task.getResponsible()); 
     mDeleteImageView.setTag(task); 
    } 

    public Task getTask() { 
     return mTask; 
    } 

    public ImageView getDeleteImageView() { 
     return mDeleteImageView; 
    } 

    public ImageView getEmailImageView() { 
     return mEmailImageView; 
    } 
} 

自定義佈局xml文件:

<?xml version="1.0" encoding="UTF-8"?> 
<id10778734.sceresini.week4.exercise3.views.TaskListItem 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:padding="5dip" > 

    <ImageView 
     android:id="@+id/list_row_layout_email_button" 
     android:layout_width="36dip" 
     android:layout_height="36dip" 
     android:layout_gravity="center_vertical" 
     android:layout_marginLeft="4dip" 
     android:layout_marginRight="5dip" 
     android:contentDescription="@string/list_row_email_icon_description" 
     android:src="@android:drawable/ic_dialog_email" /> 

    <ImageView 
     android:id="@+id/list_row_layout_priority_icon" 
     android:layout_width="24dip" 
     android:layout_height="24dip" 
     android:layout_gravity="center_vertical" 
     android:layout_marginLeft="4dip" 
     android:layout_marginRight="10dip" 
     android:contentDescription="@string/view_task_priority_icon_description" /> 

    <RelativeLayout 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical" > 

     <TextView 
      android:id="@+id/list_row_layout_task_name" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentLeft="true" 
      android:layout_centerVertical="true" 
      android:layout_toLeftOf="@+id/list_row_layout_responsible" 
      android:paddingRight="5dip" 
      android:textAppearance="@style/list_row_task_name" /> 

     <TextView 
      android:id="@id/list_row_layout_responsible" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerVertical="true" 
      android:layout_toLeftOf="@+id/list_row_layout_delete_button" 
      android:maxWidth="100dip" 
      android:textAppearance="@style/list_row_task_responsible" /> 

     <ImageView 
      android:id="@id/list_row_layout_delete_button" 
      android:layout_width="36dip" 
      android:layout_height="36dip" 
      android:layout_alignParentRight="true" 
      android:layout_centerVertical="true" 
      android:layout_marginLeft="5dip" 
      android:layout_marginRight="5dip" 
      android:contentDescription="@string/delete_task_icon_description" 
      android:src="@drawable/task_delete" /> 
    </RelativeLayout> 

</id10778734.sceresini.week4.exercise3.views.TaskListItem> 

而定製陣列適配器:

package id10778734.sceresini.week4.exercise3; 

import id10778734.sceresini.week4.exercise3.R; 
import id10778734.sceresini.week4.exercise3.tasks.Task; 
import id10778734.sceresini.week4.exercise3.views.TaskListItem; 

import java.util.ArrayList; 

import android.app.AlertDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 

public class TaskListAdapter extends BaseAdapter 
{ 

    private ArrayList<Task> mTasks; 
    private Context mContext; 
    private AlertDialog unsavedChangesDialog; 
    private TaskManagerApplication mApp; 

    public TaskListAdapter(Context context, ArrayList<Task> tasks) { 
     super(); 
     mApp = (TaskManagerApplication) context.getApplicationContext(); 
     mContext = context; 
     mTasks = tasks; 
    } 

    @Override 
    public int getCount() 
    { 
     return mTasks.size(); 
    } 

    @Override 
    public Task getItem(int position) 
    { 
     return (null == mTasks) ? null : mTasks.get(position); 
    } 

    @Override 
    public long getItemId(int position) 
    { 
     return position; 
    } 

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

     if (null == convertView) 
     { 
      tli = (TaskListItem) View.inflate(mContext, R.layout.list_row_layout, null); 
     } else 
     { 
      tli = (TaskListItem) convertView; 
     } 

     tli.setTask(mTasks.get(position)); 

     tli.getEmailImageView().setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) 
      { 
       emailTask(v); 
      } 
     }); 

     tli.getDeleteImageView().setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) 
      { 
       deleteTask(v); 
      } 
     }); 

     return tli; 
    } 

    /** 
    * deleteTask() prompts the user with an alert dialog and presents them with 
    * the option to continue with the delete request or to cancel the request. 
    * Upon confirmation, the selected Task object which is retrieved from the 
    * deleteTaskIcon tag, will be removed from the list of currentTasks. 
    * 
    * @param v 
    */ 
    protected void deleteTask(View v) 
    { 
     final Task t = (Task) v.getTag(); 
     String alertMessage = String.format(mContext.getString(R.string.delete_task_message), t.getName()); 

     unsavedChangesDialog = new AlertDialog.Builder(mContext).setTitle(R.string.delete_task_title).setMessage(alertMessage) 
     // Delete the task and refresh the adapter. 
       .setPositiveButton(R.string.delete_task_delete, new AlertDialog.OnClickListener() { 

        @Override 
        public void onClick(DialogInterface arg0, int arg1) 
        { 
         // Remove task from array list 
         mTasks.remove(t); 

         // Remove task from Database 
         mApp.deleteTask(t); 

         // Display toast message stating the task was deleted 
         mApp.displayToast(Constants.TASK_DELETED); 

         // Update listView with modified adapter 
         forceReload(); 
        } 
       }) 
       // Cancel the delete request and do nothing. 
       .setNegativeButton(R.string.delete_task_cancel, new AlertDialog.OnClickListener() { 

        @Override 
        public void onClick(DialogInterface arg0, int arg1) 
        { 
         unsavedChangesDialog.cancel(); 
        } 
       }).create(); 

     unsavedChangesDialog.show(); 
    } 

    /** 
    * emailTask() populates the selected task into an intent which allows the 
    * user to select a client to send the task. This is formatted for email 
    * clients. 
    * 
    * @param v 
    */ 
    protected void emailTask(View v) 
    { 
     // Retrieve the task that is allocated to this RowView 
     final Task t = (Task) v.getTag(); 

     // Instantiate the intent that will be used to call the email client 
     Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); 

     // Variables/Arrays to hold email attributes 
     String[] emailRecipients = { mContext.getString(R.string.email_task_to_email) }; 
     String emailType = mContext.getString(R.string.email_task_type); 
     String emailTitle = mContext.getString(R.string.email_task_title); 
     String emailSubject = String.format(mContext.getString(R.string.email_task_subject), t.getName()); 
     String emailMessage = String.format(mContext.getString(R.string.email_task_message), t.getResponsible(), t.getName(), mContext.getString(t.getPriorityStringId())); 

     // Add the email attributes to the intent 
     emailIntent.setType(emailType); 
     emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, emailRecipients); 
     emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, emailSubject); 
     emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, emailMessage); 

     // Start intent 
     mContext.startActivity(Intent.createChooser(emailIntent, emailTitle)); 
    } 

    /** 
    * Refreshes the ListView with the modified dataset. 
    */ 
    public void forceReload() 
    { 
     notifyDataSetChanged(); 
    } 
}