我想確定一個ListView包含每行不同佈局的最佳方法。我知道如何創建一個自定義行+自定義數組適配器來支持整個列表視圖的自定義行,但是如何在ListView中實現多種不同的行樣式?Android ListView每行不同的佈局
回答
既然你知道有多少類型的佈局,你可以使用這些方法。
getViewTypeCount()
- 這個方法返回的信息很多類型的行你怎麼在你的列表
getItemViewType(int position)
- 返回你應該使用基於
然後你誇大佈局位置,其佈局類型信息,只有當它的空並使用getItemViewType
確定類型。
看看this tutorial瞭解更多信息。
爲了實現結構優化,一些你已經在註釋中所描述我建議:
- 在對象存儲的觀點稱爲
ViewHolder
。它會提高速度,因爲您不必每次都在getView
方法中調用findViewById()
。見List14 in API demos。 - 創建一個通用佈局,該佈局將符合所有屬性組合,並在當前位置沒有它時隱藏某些元素。
我希望能幫到你。如果你可以提供一些XML存根與你的數據結構和信息,你想如何將它映射到行中,我將能夠給你更精確的建議。按像素。
在您的自定義數組適配器中,您可以重寫getView()方法,正如您大概熟悉的一樣。然後,您只需使用switch語句或if語句返回特定的自定義視圖,具體取決於傳遞給getView方法的位置參數。 Android很聰明,因爲它只會爲您提供適合您的位置/行的適當類型的convertView;你不需要檢查它是正確的類型。您可以通過適當地重寫getItemViewType()和getViewTypeCount()方法來幫助Android。
我知道如何創建自定義行+自定義數組適配器來支持整個列表視圖的自定義行。但是,一個listview如何支持許多不同的行風格?
您已經瞭解基礎知識。您只需讓自定義適配器根據提供的行/光標信息返回不同的佈局/視圖。
甲ListView
可以支持多個列的樣式,因爲它從AdapterView導出:
一個AdapterView是一個視圖其孩子由一個適配器確定。
如果你看一下Adapter,你會看到該帳戶使用特定行觀點方法:
abstract int getViewTypeCount()
// Returns the number of types of Views that will be created ...
abstract int getItemViewType(int position)
// Get the type of View that will be created ...
abstract View getView(int position, View convertView, ViewGroup parent)
// Get a View that displays the data ...
後兩種方法提供位置這樣你就可以使用它來確定視圖的類型您應該使用對於該行。
當然,您通常不直接使用AdapterView和Adapter,而是使用或派生自其某個子類。 Adapter的子類可能會添加更多功能,這些功能會更改如何爲不同行獲取自定義佈局。 由於用於給定行的視圖是由適配器驅動的,因此技巧是讓適配器返回給定行所需的視圖。如何做到這一點取決於特定的適配器。
例如,使用ArrayAdapter,
- 倍率
getView()
膨脹,填充,並返回所需的視圖對於給定的位置。getView()
方法通過參數convertView
包含機會重用視圖。
但使用的CursorAdapter衍生物,
- 倍率
newView()
膨脹,填充,並返回所需的視圖對於當前光標狀態(即,當前的「行」。)[你還需要覆蓋bindView
以便Widget可以重新使用視圖]
但是,要使用SimpleCursorAdapter,
- 限定
SimpleCursorAdapter.ViewBinder
與setViewValue()
方法膨脹,填充,並返回所需的視圖對於給定的行(當前光標狀態)和數據「列」。該方法只能定義「特殊」視圖,並遵循SimpleCursorAdapter對「常規」綁定的標準行爲。
查找最終使用的適配器種類的具體示例/教程。
如果我們需要在列表視圖中顯示不同類型的視圖,那麼在適配器中使用getViewTypeCount()和getItemViewType()很好,而不是切換視圖VIEW.GONE和VIEW.VISIBLE在getView中可能是非常昂貴的任務()會影響列表滾動。
請在適配器中選中getViewTypeCount()和getItemViewType()。
ListView控件是打算簡單的用例像所有的行項目相同的靜態視圖。
由於您必須創建ViewHolders並大量使用getItemViewType()
並動態顯示不同的行項目佈局xml,因此您應該嘗試使用Android API 22中提供的RecyclerView來完成此操作。它爲多視圖提供了更好的支持和結構類型。
看看這個tutorial關於如何使用RecyclerView來做你正在尋找的東西。
看看下面的代碼。
首先,我們創建自定義佈局。在這種情況下,有四種類型。
even.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ff500000"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:textColor="@android:color/white"
android:layout_width="match_parent"
android:layout_gravity="center"
android:textSize="24sp"
android:layout_height="wrap_content" />
</LinearLayout>
odd.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ff001f50"
android:gravity="right"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:textColor="@android:color/white"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:textSize="28sp"
android:layout_height="wrap_content" />
</LinearLayout>
white.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ffffffff"
android:gravity="right"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:textColor="@android:color/black"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:textSize="28sp"
android:layout_height="wrap_content" />
</LinearLayout>
black.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ff000000"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:textColor="@android:color/white"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:textSize="33sp"
android:layout_height="wrap_content" />
</LinearLayout>
然後,我們創建listview項目。在我們的例子中,用一個字符串和一個類型。
public class ListViewItem {
private String text;
private int type;
public ListViewItem(String text, int type) {
this.text = text;
this.type = type;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
之後,我們創建一個視圖持有者。強烈建議這樣做,因爲Android操作系統會保留佈局參考,以便在物品消失並重新出現在屏幕上時重複使用。如果你不使用這種方法,你的項目每次出現在屏幕上的Android操作系統將創建一個新的並導致你的應用程序泄漏內存。最後,我們創建了我們的自定義適配器重寫getViewTypeCount()和getItemViewType(int position)。
public class CustomAdapter extends ArrayAdapter {
public static final int TYPE_ODD = 0;
public static final int TYPE_EVEN = 1;
public static final int TYPE_WHITE = 2;
public static final int TYPE_BLACK = 3;
private ListViewItem[] objects;
@Override
public int getViewTypeCount() {
return 4;
}
@Override
public int getItemViewType(int position) {
return objects[position].getType();
}
public CustomAdapter(Context context, int resource, ListViewItem[] objects) {
super(context, resource, objects);
this.objects = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
ListViewItem listViewItem = objects[position];
int listViewItemType = getItemViewType(position);
if (convertView == null) {
if (listViewItemType == TYPE_EVEN) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.type_even, null);
} else if (listViewItemType == TYPE_ODD) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.type_odd, null);
} else if (listViewItemType == TYPE_WHITE) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.type_white, null);
} else {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.type_black, null);
}
TextView textView = (TextView) convertView.findViewById(R.id.text);
viewHolder = new ViewHolder(textView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.getText().setText(listViewItem.getText());
return convertView;
}
}
而且我們的活動是這樣的:
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // here, you can create a single layout with a listview
listView = (ListView) findViewById(R.id.listview);
final ListViewItem[] items = new ListViewItem[40];
for (int i = 0; i < items.length; i++) {
if (i == 4) {
items[i] = new ListViewItem("White " + i, CustomAdapter.TYPE_WHITE);
} else if (i == 9) {
items[i] = new ListViewItem("Black " + i, CustomAdapter.TYPE_BLACK);
} else if (i % 2 == 0) {
items[i] = new ListViewItem("EVEN " + i, CustomAdapter.TYPE_EVEN);
} else {
items[i] = new ListViewItem("ODD " + i, CustomAdapter.TYPE_ODD);
}
}
CustomAdapter customAdapter = new CustomAdapter(this, R.id.text, items);
listView.setAdapter(customAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView adapterView, View view, int i, long l) {
Toast.makeText(getBaseContext(), items[i].getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
現在裏面mainactivity.xml 創建一個列表視圖這樣
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.shivnandan.gygy.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/listView"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="100dp" />
</android.support.design.widget.CoordinatorLayout>
- 1. 具有不同佈局的ListView行
- 2. Android - 每行不同高度的ListView/getView()
- 3. ListView與dyamically選擇每行佈局
- 4. Android的佈局的ListView
- 5. 佈局中的ListView和單獨的ListView有什麼不同?
- 6. listview Android中的佈局
- 7. Android - ListView佈局兩行列表項
- 8. 使用多行佈局實現Android ListView
- 9. 回收具有不同行佈局的ListView行
- 10. android listview佈局錯誤
- 11. android tab佈局listview不可點擊
- 12. android listview不會貼在佈局頂部
- 13. ListView ContextAction不遵循佈局
- 14. 動態佈局(每頁不同的佈局)
- 15. 在ListView中的每一行的自定義佈局
- 16. 的Android的ListView MapView的佈局問題
- 17. Android的ListView項目的佈局,如Twitter
- 18. 的Android - BottomNavigationMenu和ListView的線性佈局
- 19. C#ListView每行不同的文本
- 20. 2個不同的佈局爲每一行的類型
- 21. Android listview裏面的相對佈局
- 22. Android佈局在相關佈局下的Listview高度調整
- 23. ListView佈局
- 24. ListView佈局
- 25. Android - 如何重用不同佈局XML的包裝佈局?
- 26. Android ListView與2組其中每一行是不同的對象
- 27. HTML網格佈局具有不同的列每行
- 28. 使用不同Android API的XML佈局
- 29. 不同屏幕尺寸的android佈局
- 30. Android中的不同鍵盤佈局
更新:使用演示了多行佈局Android的RecyclerView HTTP ://code2concept.blogspot.in/2015/10/android-multiple-row-layout-using.html – nitesh 2015-10-17 06:00:45