2014-01-24 2 views
4

У меня есть listView. Ячейки имеют переменную высоту. Это вызывает проблему при переработке ячеек - переработанные ячейки могут иметь неправильную высоту. Отключение утилизации делает прокрутку слишком изменчивой. Как я могу получить правильную высоту при повторном использовании ячеек?Android listView переработка ячеек с ячейками с переменным размером

EDIT: высоты различаются по всему месту. Существует короткий список возможных значений.

+0

Имеет ли каждый ряд другой размер? Или даже когда у вас разные высоты, вы знаете, сколько у вас будет разных высот? – nKn

+0

Вы использовали getitemviewtype? – Blackbelt

+0

Я не думаю, что есть решение вашей проблемы (бесконечные разные типы + утилизация). В любом случае, я рассмотрел вопрос, поэтому давайте посмотрим, появился ли какой-нибудь интересный ответ. –

ответ

0

ДВА ТИПА CELL

Обычно проблема возникает из GetView. Я не уверен, что вы действительно ищете, потому что не предоставляете свой собственный адаптер. Тем не менее, я даю вам пример с двумя разными типами ячеек, но ячейка содержит только текстовое представление.

В этом случае все ячейки полностью отрегулированы с помощью утилизации. Читайте внимательно и расширяйте/изменяйте в соответствии с вашими потребностями.

в вашем CustomAdapter

private final class CustomArrayAdapter extends ArrayAdapter<String> { 
    //the fastest is to get the layout inflater once and not each time getView is called 
    private LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    public CustomArrayAdapter(Context context, int resource, int textViewResourceId, String[] objects) { 
     super(context, resource, textViewResourceId, objects); 
    } 

    ... 

    //here depending on the item position determine if cell is of type 1 or 2 
    @Override 
    public int getItemViewType(int position) { 
     if (/* your type 1 criteria is match */) { 
      return TYPE_1; 
     } else { 
      return TYPE_2; 
     } 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder = null; 
     int type = getItemViewType(position); 
     if (convertView == null) { 
      holder = new ViewHolder(); 
      switch (type) { 
       case TYPE_1: 
        convertView = mInflater.inflate(R.layout.row_of_type_1, parent, false); 
        holder.text = (TextView) convertView.findViewById(R.id.textview_type_1); 
        break; 
       case TYPE_2: 
        convertView = mInflater.inflate(R.layout.row_of_type_2, parent, false); 
        holder.text = (TextView) convertView.findViewById(R.id.textview_type_2); 
        break; 
      } 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     //get the text for that specific cell and set it 
     holder.text.setText(getMyCustomTextForThisCell()); 

     return convertView; 
    } 
} 

static class ViewHolder {  
    TextView text; 
} 

ОДНОЙ КЛЕТКИ ТИПА

В случае, если вы просто нуждаетесь в ячейке одного типа с одним TextView в нем и хотите поместить текст отличается длина во всей ячейке и ячейка адаптируют ее высоту автоматически, просто используйте следующий код в своем CustomAdapter

private final class CustomArrayAdapter extends ArrayAdapter<String> { 
    //the fastest is to get the layout inflater once and not each time getView is called 
    private LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    public CustomArrayAdapter(Context context, int resource, int textViewResourceId, String[] objects) { 
     super(context, resource, textViewResourceId, objects); 
    } 

    ... 

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

     if (convertView == null) { 
      holder = new ViewHolder(); 
      convertView = mInflater.inflate(R.layout.row_type, parent, false); 
      holder.text = (TextView) convertView.findViewById(R.id.textview_in_your_row); 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     //get the text for that specific cell and set it 
     holder.text.setText(getMyCustomTextForThisCell()); 

     return convertView; 
    } 
} 

static class ViewHolder {  
    TextView text; 
} 

CELL РАСПОЛ

В примере я даю файл row_type.xml (файл макета вашей строки) должен выглядеть так:

<?xml version="1.0" encoding="utf-8"?> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/textview_in_your_row" 
    android:paddingLeft="6dp" 
    android:paddingRight="6dp" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"/> 

не забудьте android:layout_height="wrap_content" или ячейка не будет изменять размер


SIDE К.П

Эта сторона комментарий не говорит о О.П. вопросе, однако, если люди приходят сюда из-за клеток рециркуляции слова в названии они могут быть заинтересованы в том, что я даю полный пример рециркуляции клеток с EditText здесь

The content of EditText contained into a Android ListView isn't saved

+0

Ваш подход был бы таким, чтобы идти ** ЕСЛИ ** ОП не добавил: «высоты меняются повсюду. Существует не короткий список возможных значений». –

+0

Я не понимаю смысла. Что он подразумевает под «разбросом по всему месту». Я имею в виду, что у меня сначала возникла проблема с переработкой только с одним типом, поскольку я не делал setTag в правильном месте. – HpTerm

+1

Я не могу быть уверен, но я подозреваю, что он означает, что все взгляды могут иметь разные типы. Поскольку два представления должны иметь один и тот же тип, который должен быть преобразован друг в друга, если все они имеют разные типы, то переработка ничего не сделает. –

0

Вот как я решил его с помощью Xamarin.

public override View GetView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 

     int type = GetItemViewType(position); 
     if (convertView == null) 
     { 
      holder = new ViewHolder(); 
      convertView = context.LayoutInflater.Inflate(Resource.Layout.my_row_layout, parent, false); 
      holder.myTextView = FindViewById<TextView>(Resource.Id.viewRow); 
      convertView.Tag = holder; 
     } 
     else 
     { 
      holder = (ViewHolder)convertView.Tag; 
      int heightWeWant = heights[type]; 
      if (holder.myTextView.Height != heightWeWant) //height we have isn't what we want 
      { 
       AbsListView.LayoutParams parms = new AbsListView.LayoutParams(LinearLayout.LayoutParams.MatchParent, heightWeWant); //Width, Height //resize the view to the height we want 
       convertView.LayoutParameters = parms; 
      } 
      convertView.Tag = holder; 
     } 

     holder.myText = "Some text here"; 

     return convertView; 
    } 
Смежные вопросы