我想创建一个自定义ListView,其中包含节标题和一个包含两个文本视图的行布局
我已经解决了很多教程和SO问题,通过这项工作,我能够创建一个带有节标题的自定义ListView,但它们没有固定。
我跟着this SO answer;在这种情况下,当我完全遵循SO答案中描述的内容时,所以行的布局具有带有子列表的TextView,然后标题被固定,但是当我使用我自己的布局时,它正在工作但是标题不再固定。
我想把这些标题固定。代码如下;提前感谢您的帮助。
注意:我了解开源库,例如amazing-list-view,PinnedHeadersSections等。
我想要一个定制的;在这方面的任何形式的帮助将不胜感激。
header.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="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:gravity="center"
android:text="@string/header"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
header.xml(具有子列表视图的替代header.xml,如SO答案中的固定标头)
<?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="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:gravity="center"
android:text="@string/header"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="150dp" >
</ListView>
</LinearLayout>
row_layout.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="match_parent"
android:orientation="horizontal"
android:weightSum="5" >
<TextView
android:id="@+id/day"
android:layout_width="0dp"
android:background="#000"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/description"
android:layout_width="0dp"
android:background="#000"
android:layout_height="wrap_content"
android:layout_weight="4" />
</LinearLayout>
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
HeadersListActivity.java
public class HeadersListActivity extends ListActivity implements OnClickListener{
ListView listView ;
@SuppressWarnings("rawtypes")
static class SimpleAdapter extends ArrayAdapter implements OnScrollListener,HeadersListAdapter{
private LayoutInflater inflator;
private List list;
private ListView listView;
@SuppressWarnings("unused")
private Activity activity;
private static class ViewHolder {
private TextView header;
private TextView day;
private TextView description;
int previousTop = 0;
public ViewHolder(){}
}
@SuppressWarnings("unchecked")
public SimpleAdapter(Activity activity,ArrayList<Item> list, ListView listView){
super(activity.getApplicationContext(),0,list);
this.activity = activity;
this.list = list;
this.listView = listView;
this.listView.setOnScrollListener(this);
inflator = LayoutInflater.from(activity.getApplicationContext());
}
@Override
public View getView(int position, View convertView, android.view.ViewGroup parent) {
ViewHolder holder = null ;
View itemView = convertView;
Item item = (Item) list.get(position);
if(item.type == Item.SECTION){
holder = new ViewHolder();
itemView = inflator.inflate(R.layout.header, null);
holder.header = (TextView) itemView.findViewById(R.id.textView1);
holder.header.setTextColor(Color.DKGRAY);
holder.header.setText(item.text);
itemView.setTag(holder);
itemView.setBackgroundColor(Color.GREEN);
} else {
if(itemView == null){
itemView = inflator.inflate(R.layout.row_layout, null);
holder = new ViewHolder();
holder.day = (TextView)itemView.findViewById(R.id.day);
holder.description = (TextView)itemView.findViewById(R.id.description);
itemView.setTag(holder);
} else holder = (ViewHolder)itemView.getTag();
if(item.type == Item.ITEM){
holder.day.setTextColor(Color.DKGRAY);
holder.day.setBackgroundColor(Color.WHITE);
holder.day.setText(item.toString());
holder.description.setTextColor(Color.DKGRAY);
holder.description.setBackgroundColor(Color.WHITE);
holder.description.setText(item.getDescription());
}
}
return itemView;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
return ((Item) list.get(position)).type;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
for(int i=0; i < listView.getChildCount(); i++){
View child = listView.getChildAt(i);
ViewHolder holder = (ViewHolder) child.getTag();
Item item = (Item) list.get(i);
if(item.type == Item.SECTION && (holder.header != null)){
//if the view is the first item at the top we will do some processing
if(i == 0){
boolean isAtBottom = child.getHeight() <= holder.header.getBottom();
int offset = holder.previousTop - child.getTop();
if(!(isAtBottom && offset > 0)){
holder.previousTop = child.getTop();
holder.header.offsetTopAndBottom(offset);
holder.header.invalidate();
}
} //if the view is not the first item it "may" need some correction because of view re-use
else if (holder.header.getTop() != 0) {
int offset = -1 * holder.header.getTop();
holder.header.offsetTopAndBottom(offset);
holder.previousTop = 0;
holder.header.invalidate();
}
}
}
}
@Override
public void onScrollStateChanged(AbsListView arg0, int arg1) {
}
}
static class Item {
public static final int SECTION = 0;
public static final int ITEM = 1;
private final int type;
private String text ;
private String description ;
public int sectionPosition;
public int listPosition;
public Item(int type,String text){
this.type = type;
this.text = text;
}
public Item(int type,String text,String description){
this.type = type;
this.text = text;
this.description = description;
}
public String toString(){
return text;
}
public void setDescription(String description){
this.description = description;
}
public String getDescription(){
return this.description;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(android.R.id.list);
String[] headers = new String[] { "Section A",
"Section B",
"Section C",
"Section D",
"Section E",
"Section F",
"Section G",
"Section H"
};
String[] values = new String[] { "Android List View",
"Adapter implementation",
"Simple List View In Android",
"Create List View Android",
"Android Example",
"List View Source Code",
"List View Array Adapter",
"Android Example List View"
};
String[] numbers = new String[] { "One-",
"Two-",
"Three-",
"Four-",
"Five-",
"Six-",
"Seven-",
"Eight-"
};
ArrayList<Item> itemList = new ArrayList<Item>();
int sectionPosition=0,listPosition=0;
for(int i=0;i<headers.length;i++){
Item section = new Item(Item.SECTION,headers[i]);
section.sectionPosition = sectionPosition;
section.listPosition = listPosition++;
itemList.add(section);
for(int j=0;j<values.length;j++){
Item item = new Item(Item.ITEM,numbers[j],values[j]);
item.sectionPosition= sectionPosition;
item.listPosition= listPosition++;
itemList.add(item);
}
}
setListAdapter(new SimpleAdapter(HeadersListActivity.this, itemList , listView));
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Item item = (Item) getListView().getAdapter().getItem(position);
if (item != null) {
if(item.type == Item.ITEM)
Toast.makeText(this, "Item " + position + ": " + item.text+""+item.description, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Item " + position, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onClick(View v) {
Toast.makeText(this, "Item: " + v.getTag() , Toast.LENGTH_SHORT).show();
}
}