2012-02-22 3 views
0

Я должен создать проект, аналогичный проекту ff. рис. (Приношу извинения за использование siily pic, я должен заниматься тем, что легко доступно).
enter image description hereМногострочный списокViewView с ImageView с левой стороны


Я бы не сказал, что я был лучшим подходом в создании «динамичный» ListView, но я был бы рад просто сделать то, что я в настоящее время работы. В любом случае моя реализация выглядит следующим образом:

public class MultiLineListViewActivity extends Activity { 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    ArrayList<SearchResults> searchResults = getSearchResults(); 

    ListView listView = (ListView) findViewById(R.id.listView); 
    listView.setAdapter(new MyCustomBaseAdapter(this, searchResults)); 
} 

private ArrayList<SearchResults> getSearchResults() { 
    ArrayList<SearchResults> results = new ArrayList<SearchResults>(); 

    SearchResults sr1 = new SearchResults(); 
    sr1.setName("Name 1"); 
    sr1.setPhone("12345"); 
    SearchResults.setIcon(R.drawable.pic_one); 
    results.add(sr1); 

    sr1 = new SearchResults(); 
    sr1.setName("Name 2"); 
    sr1.setPhone("123456"); 
    SearchResults.setIcon(R.drawable.pic_two); 
    results.add(sr1); 

    ... 

    return results; 
} 
} 


SearchResults общественного класса {

private String name; 
private String phone; 
public static ArrayList<Integer> iconsList = new ArrayList<Integer>(); 

public void setName(String name) { 
    this.name = name; 
} 

public void setPhone(String phone) { 
    this.phone = phone; 
} 

public static void setIcon(int i) { 
    iconsList.add(i); 
} 

public String getName() { 
    return this.name; 
} 

public String getPhone() { 
    return this.phone; 
} 
} 


public class MyCustomBaseAdapter extends BaseAdapter { 

private ArrayList<SearchResults> searchArrayList; 
private LayoutInflater layoutInflater; 
private Context context; 

public MyCustomBaseAdapter(Context context, ArrayList<SearchResults> results) { 
    this.searchArrayList = results; 
    //this.context = context; 
    layoutInflater = LayoutInflater.from(context); 
} 

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

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

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

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    ViewHolder holder; 
    ImageView imageView; 

    if(convertView == null) { 
     convertView = layoutInflater.inflate(R.layout.custom_row_view, null); 

     holder = new ViewHolder(); 
     holder.txtName = (TextView) convertView.findViewById(R.id.name); 
     holder.txtPhone = (TextView) convertView.findViewById(R.id.phone); 

     imageView = new ImageView(context); 

     convertView.setTag(holder); 
    } 
    else { 
     //imageView = (ImageView) convertView; 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    imageView = new ImageView(context); 
    imageView.setImageResource(SearchResults.iconsList.get(position)); 

    holder.txtName.setText(searchArrayList.get(position).getName()); 
    holder.txtPhone.setText(searchArrayList.get(position).getPhone()); 

    return convertView; 
} 

class ViewHolder { 
    TextView txtName; 
    TextView txtPhone; 
} 


Приведенный выше код был успешно отображая Название и Телефон строк в ListView, это добавление изображения, которое дает мне «Force Close».

Обратите внимание на прокомментированную строку imageView = (ImageView) convertView; Я уменьшил его до той конкретной строки, что удаление комментариев приводит к сбою приложения.

ответ

3

Примечание: всякий раз, когда вы получаете силу, о которой вы спрашиваете в вопросе StackOverflow, отправьте полную трассировку стека.

Вы всегда создаете новый ImageView, когда на самом деле вам, вероятно, не нужно создавать его вообще. Он должен быть определен в вашем настраиваемом макете элементов (который вы, вероятно, должны также разместить в этом случае), как и TextView. Вы можете использовать findViewById таким же образом и получить его.

+0

Ваше предложение было на месте! Как вы уже сказали, я добавил ImageView в layout.custom_row_view.xml, удалил ВСЕ объявления и экземпляры imageView внутри getView(), сделал вложенные LinearLayouts (RelativeLayout тоже работает), чтобы упорядочить взгляды, подобные этому примеру .. и viola ! Он работает по назначению, спасибо! –

3

kabuko - правый по обе стороны. (ОБНОВЛЕНИЕ: также его комментарий ниже не следует игнорировать.) Я предполагаю, что ваш layout/custom_row_view - это LinearLayout, что означает, что прокомментированная строка пытается принудить LinearLayout к ImageView, что да приведет к возникновению исключения. Кроме того, ваш ViewHolder класс является излишним, просто определить те TextViews как переменные в getView() как так ...

// Assuming that layout/custom_row_view is a LinearLayout... 
getView(yadda) { 
    LinearLayout row; 
    ImageView imageView; 
    TextView txtName, txtPhone; 

    if (convertView == null) { 
     row = // inflate a new one 
    } else { 
     row = // get the old one 
    } 

    // fetch the views 
    imageView = row.findViewById(...); 
    txtName = row.findViewById(...); 
    txtPhone = row.findViewById(...); 

    // fill the views 
    imageView.setImageResource(...); 
    txtName.setContent(...); 
    txtPhone.setContent(...); 

    return row; 
} 

Ciao.

+1

Класс 'ViewHolder' на самом деле является эффективным повышением производительности. 'findViewById' не всегда дешево, и иногда стоит съесть немного меньшую память, чтобы сэкономить на этой обработке. См. [This] (http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html) для примера. – kabuko

Смежные вопросы