2013-06-14 26 views
5

Tworzyłem aplikację dla systemu Android, w której używam ListView. ListView składa się z elementów listy CheckedTextView. Moja aktywność zawiera EditText u góry, tekstView poniżej i przycisk na dole. Przestrzeń pomiędzy TextView i przyciskiem to obszar zajmowany przez ListView. Teraz, ponieważ mój ListView zawiera raczej mało elementów, całe miejsce listy ListView nie jest przez nie zajęte. Również przestrzeń pozostawiona oczywiście różni się w zależności od urządzenia. Chcę wiedzieć, czy istnieje sposób na zmianę wysokości wiersza listy ListView, tak aby obejmowała całą przestrzeń przydzieloną do ListView. A jeśli pojawi się potrzeba dodania niektórych elementów, wysokość wiersza może się odpowiednio dopasować. Podałem kilka fragmentów kodu poniżej, aby łatwo było zrozumieć, jaki jest mój układ.Dynamicznie zmieniaj wysokość wiersza w widoku listy na podstawie liczby elementów listy

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
android:background="#D0D0D0" 
tools:context=".MainActivity" > 

<Button 
    android:id="@+id/addcourse" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" 
    android:text="Add Course" /> 

<EditText 
    android:id="@+id/coursenameet" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignParentTop="true" 
    android:layout_centerHorizontal="true" 
    android:ems="10" 
    android:layout_marginBottom="2dp" 
    android:layout_marginTop="2dp" 
    android:hint="Course Name" 
    android:inputType="textCapWords" > 

    <requestFocus /> 
</EditText> 

<View 
    android:id="@+id/divider" 
    android:layout_width="match_parent" 
    android:layout_height="3dp" 
    android:layout_below="@+id/coursenameet" 
    android:layout_marginBottom="5dp" 
    android:layout_marginTop="5dp" 
    android:background="@android:color/darker_gray" > 
</View> 

<TextView 
    android:id="@+id/weekdaytv" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_below="@+id/divider" 
    android:layout_marginBottom="3dp" 
    android:layout_marginTop="3dp" 
    android:layout_centerHorizontal="true" 
    android:text="Select weekdays for this Course" > 
</TextView> 

<ListView 
    android:id="@+id/listView1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_above="@+id/addcourse" 
    android:layout_below="@+id/weekdaytv" 
    android:divider="#FFFFFF" 
    android:dividerHeight="2px"> 

</ListView> 

</RelativeLayout> 

Pozycje są CheckedTextViews, które są realizowane za pomocą BaseAdapter. Widok metoda klasy BaseAdapter jest

public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    int colorpos = position % colors.length; 
    if(v == null){ 
     LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.listviewitem, null); 
    } 
    CheckedTextView newrow = (CheckedTextView) v.findViewById(R.id.checkedtextview); 
    v.setBackgroundColor(colors[colorpos]); 
    newrow.setTextColor(Color.BLACK); 
    newrow.setText(items[position]); 
    return v; 
} 

EDIT: Fragment z działalności Główne

lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 
    adapter = new ItemsAdapter(MainActivity.this, weekdays, 6, lv.getBottom() - lv.getTop()); 
    lv.setAdapter(adapter); 

    lv.setOnItemClickListener(new OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 
       long arg3) { 
      CheckedTextView ctv = (CheckedTextView) arg1; 
      adapter.toggle(ctv); 
     } 
    }); 
+0

Got żadnego właściwe rozwiązanie? –

Odpowiedz

0

Aby ustawić ListView wypełnić całą przestrzeń przydzielona, ​​można ustawić atrybut ListView w XML:

android:fillViewport=”true” 

Lub w kodzie:

myListView.setFillViewport(true); 

Jeśli chcesz zmienić rozmiar komórki, możesz obliczyć wartość ViewParams, którą chcesz ustawić. Na przykład, dla pojedynczej komórce, można użyć:

AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT, AbsListView.LayoutParams.FILL_PARENT); 
v.setLayoutParams(params); 

Dla n komórek, można obliczyć rozmiar pionowy na podstawie rozmiaru ListView:

int n = /* number of cells */ 3; 
int height = (myListView.getBottom() - myListView.getTop()); 
AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT, height/n); 
v.setLayoutParams(params); 
+0

Daje błąd: - Otwarta oferta jest oczekiwana dla atrybutu "android: fillViewport" powiązanego z typem elementu "ListView". Proszę o pomoc. – tintin

+0

Proszę mi powiedzieć, co jest myCell w ostatnim wierszu odpowiedzi. Nie mam odpowiedniej wartości w moim kodzie. Powiedz mi też, czy ma to nastąpić w głównym działaniu, czy w klasie BaseAdapter, którą mam. – tintin

+0

@tintin, aktualizuję kod, aby użyć Twojej zmiennej v. – Phil

11

Hi utworzyć klasę w ten sposób:

public class Utility { 

    public static void setListViewHeightBasedOnChildren(ListView listView) { 
     ListAdapter listAdapter = listView.getAdapter(); 
     if (listAdapter == null) { 
      // pre-condition 
      return; 
     } 

     int totalHeight = 0; 
     int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST); 
     for (int i = 0; i < listAdapter.getCount(); i++) { 
      View listItem = listAdapter.getView(i, null, listView); 
      listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED); 
      totalHeight += listItem.getMeasuredHeight(); 
     } 

     ViewGroup.LayoutParams params = listView.getLayoutParams(); 
     params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); 
     listView.setLayoutParams(params); 
     listView.requestLayout(); 
    } 


} 

Wywołanie tej metody w miejscu, w którym chcesz dynamicznie zmieniać wysokość wiersza w widoku listy.

Utility.setListViewHeightBasedOnChildren(YourListView); 

Po więcej Reference .. Mam nadzieję, że to ci pomoże.

+0

Ogłosiłem pojawienie się moich wierszy w klasie BaseAdapter. Proszę powiedz mi, co dokładnie zamierzasz zrobić? Również ustawiam mój adapter za pomocą: - lv.setAdapter (adapter); Czy mam nazwać tę metodę zaraz po tym? Załóżmy, że mam teraz ustaloną liczbę wierszy i nie dodaje w tej chwili żadnych wierszy. – tintin

+1

po prostu zadeklaruj swój listview w tej metodzie. da ci dokładnie to, czego chcesz. – Nirmal

+0

Naprawdę przepraszam, ale nie rozumiem cię. Zmieniłem moje pytanie i umieściłem fragment kodu głównego działania, aby zobaczyć, co dokładnie robię. Zasugeruj, gdzie powinienem nazwać tę metodę. – tintin

0

Dla tych, którzy wciąż mam błąd w

listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED); 

napisać te linie kodu, tak.

if (ListItem instancją ViewGroup)

listItem.setLayoutParams (nowe LayoutParams (LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

 listItem.measure(0, 0);