Android ListView 헤더
곳곳에 이벤트가있는 ListView가 있습니다. 이벤트는 날짜별로 정렬되어 매일 날짜가 헤더를 만들고 있습니다.
그 목록을 채우는 방법은 다음과 가능합니다.
ArrayList<TwoText> crs = new ArrayList<TwoText>();
crs.add(new TwoText("This will be header", event.getDate()));
for (Event event : events) {
crs.add(new TwoText(event.getStartString() + "-" + event.getEndString(), event.getSubject()));
}
arrayAdapter = new TwoTextArrayAdapter(this, R.layout.my_list_item, crs);
lv1.setAdapter(arrayAdapter);
이것이 내 클래스 TwoText의 모습입니다.
public class TwoText {
public String classID;
public String state;
public TwoText(String classID, String state) {
this.classID = classID;
this.state = state;
}
}
이것이 내 TwoTextArrayAdapter 클래스의 모습입니다.
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class TwoTextArrayAdapter extends ArrayAdapter<TwoText> {
private ArrayList<TwoText> classes;
private Activity con;
TextView seperator;
public TwoTextArrayAdapter(Activity context, int textViewResourceId, ArrayList<TwoText> classes) {
super(context, textViewResourceId, classes);
this.con = context;
this.classes = classes;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.my_list_item, null);
}
TwoText user = classes.get(position);
if (user != null) {
TextView content1 = (TextView) v.findViewById(R.id.list_content1);
TextView content2 = (TextView) v.findViewById(R.id.list_content2);
if (content1 != null) {
content1.setText(user.classID);
}
if(content2 != null) {
content2.setText(user.state);
}
}
return v;
}
}
그리고 이것은 my_list_item.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="vertical" >
<TextView
style="?android:attr/listSeparatorTextViewStyle"
android:id="@+id/separator"
android:text="Header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#757678"
android:textColor="#f5c227" />
<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/list_content1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dip"
android:clickable="false"
android:gravity="center"
android:longClickable="false"
android:paddingBottom="1dip"
android:paddingTop="1dip"
android:text="sample"
android:textColor="#ff7f1d"
android:textSize="17dip"
android:textStyle="bold" />
<TextView
android:id="@+id/list_content2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dip"
android:clickable="false"
android:gravity="center"
android:linksClickable="false"
android:longClickable="false"
android:paddingBottom="1dip"
android:paddingTop="1dip"
android:text="sample"
android:textColor="#6d6d6d"
android:textSize="17dip" />
</LinearLayout>
</LinearLayout>
내가 지금하고있는 일은 헤더를 일반 목록처럼 추가하는 것이지만 헤더처럼 헤더를 선호하며 내 경우에는 날짜가 있습니다.
헤더의 XML 에이 코드가 있습니다.
<TextView
style="?android:attr/listSeparatorTextViewStyle"
android:id="@+id/separator"
android:text="Header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#757678"
android:textColor="#f5c227" />
할 때 숨기고 필요할 때 표시 할 나머지 코드를 엉망으로 만들었습니다. 몇 가지 안내를 더 시도했지만 효과가 있습니다.
누구든지 그렇게 쉬운 방법을 안내해 줄 수 있습니까?
방법은 다음과 가변합니다. 키는 클래스의 getItemViewType 및 getViewTypeCount 입니다 Adapter
. getViewTypeCount
리스트에있는 아이템의 수를 반환합니다.이 경우 헤더 아이템과 이벤트 아이템이 있습니다. 입력에 getItemViewType
어떤 유형이 있는지 확인해야합니다 .View
position
당신에게 안드로이드는 올바른 유형을 통과 처리됩니다 View
에 convertView
자동으로.
아래 코드 결과는 다음과 가변됩니다.

먼저 두 가지 목록 항목 유형이 구현할 인터페이스가 있습니다.
public interface Item {
public int getViewType();
public View getView(LayoutInflater inflater, View convertView);
}
그런 다음 목록을 가져와 어댑터가 있습니다. Item
public class TwoTextArrayAdapter extends ArrayAdapter<Item> {
private LayoutInflater mInflater;
public enum RowType {
LIST_ITEM, HEADER_ITEM
}
public TwoTextArrayAdapter(Context context, List<Item> items) {
super(context, 0, items);
mInflater = LayoutInflater.from(context);
}
@Override
public int getViewTypeCount() {
return RowType.values().length;
}
@Override
public int getItemViewType(int position) {
return getItem(position).getViewType();
}
@Override public View getView(int position, View convertView, ViewGroup parent) { return getItem(position).getView(mInflater, convertView); }
스크롤 할 때 더 나은 성능을 편집 ..를 볼 수 있습니다.
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int rowType = getItemViewType(position);
View View;
if (convertView == null) {
holder = new ViewHolder();
switch (rowType) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.task_details_row, null);
holder.View=getItem(position).getView(mInflater, convertView);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.task_detail_header, null);
holder.View=getItem(position).getView(mInflater, convertView);
break;
}
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
public static class ViewHolder {
public View View; }
}
그런 다음 구현 클래스를 Item
만들고 올바른 레이아웃을 부풀립니다. 귀하의 경우에는 Header
수업 및 수업과 같은 것이 ListItem
있습니다.
public class Header implements Item {
private final String name;
public Header(String name) {
this.name = name;
}
@Override
public int getViewType() {
return RowType.HEADER_ITEM.ordinal();
}
@Override
public View getView(LayoutInflater inflater, View convertView) {
View view;
if (convertView == null) {
view = (View) inflater.inflate(R.layout.header, null);
// Do some initialization
} else {
view = convertView;
}
TextView text = (TextView) view.findViewById(R.id.separator);
text.setText(name);
return view;
}
}
그리고 ListItem
수업
public class ListItem implements Item {
private final String str1;
private final String str2;
public ListItem(String text1, String text2) {
this.str1 = text1;
this.str2 = text2;
}
@Override
public int getViewType() {
return RowType.LIST_ITEM.ordinal();
}
@Override
public View getView(LayoutInflater inflater, View convertView) {
View view;
if (convertView == null) {
view = (View) inflater.inflate(R.layout.my_list_item, null);
// Do some initialization
} else {
view = convertView;
}
TextView text1 = (TextView) view.findViewById(R.id.list_content1);
TextView text2 = (TextView) view.findViewById(R.id.list_content2);
text1.setText(str1);
text2.setText(str2);
return view;
}
}
그리고 Activity
그것을 표시 하는 간단한
public class MainActivity extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Item> items = new ArrayList<Item>();
items.add(new Header("Header 1"));
items.add(new ListItem("Text 1", "Rabble rabble"));
items.add(new ListItem("Text 2", "Rabble rabble"));
items.add(new ListItem("Text 3", "Rabble rabble"));
items.add(new ListItem("Text 4", "Rabble rabble"));
items.add(new Header("Header 2"));
items.add(new ListItem("Text 5", "Rabble rabble"));
items.add(new ListItem("Text 6", "Rabble rabble"));
items.add(new ListItem("Text 7", "Rabble rabble"));
items.add(new ListItem("Text 8", "Rabble rabble"));
TwoTextArrayAdapter adapter = new TwoTextArrayAdapter(this, items);
setListAdapter(adapter);
}
}
의 레이아웃 R.layout.header
<?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
style="?android:attr/listSeparatorTextViewStyle"
android:id="@+id/separator"
android:text="Header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#757678"
android:textColor="#f5c227" />
</LinearLayout>
의 레이아웃 R.layout.my_list_item
<?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/list_content1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dip"
android:clickable="false"
android:gravity="center"
android:longClickable="false"
android:paddingBottom="1dip"
android:paddingTop="1dip"
android:text="sample"
android:textColor="#ff7f1d"
android:textSize="17dip"
android:textStyle="bold" />
<TextView
android:id="@+id/list_content2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dip"
android:clickable="false"
android:gravity="center"
android:linksClickable="false"
android:longClickable="false"
android:paddingBottom="1dip"
android:paddingTop="1dip"
android:text="sample"
android:textColor="#6d6d6d"
android:textSize="17dip" />
</LinearLayout>
의 레이아웃 R.layout.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"
tools:context=".MainActivity" >
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
또한 더 ViewHolders
좋아 지고 사용하고 , 혹식으로 물건을로드하거나 원하는대로 할 수 있습니다.
항목 (자식)을 구분하기 위해 헤더 (그룹)가 있는 ExpandableListView 를 찾고있을 것입니다 .
주제에 대한 좋은 튜토리얼 : here .
대안으로, 이 사용 사례를 위해 멋진 라이브러리가 있습니다. 따라서 어댑터에 저장된 데이터를 기반으로 헤더를 생성해야합니다. 이를 Rolodex 어댑터라고하며 함께 사용 ExpandableListViews
합니다. 쉽게 사용할 수 있습니다.
OP의 Event
언어를 사용하고 헤더를 알면 헤더 Date
와 관련이 있습니다.
활동
//There's no need to pre-compute what the headers are. Just pass in your List of objects.
EventDateAdapter adapter = new EventDateAdapter(this, mEvents);
mExpandableListView.setAdapter(adapter);
어댑터
private class EventDateAdapter extends NFRolodexArrayAdapter<Date, Event> {
public EventDateAdapter(Context activity, Collection<Event> items) {
super(activity, items);
}
@Override
public Date createGroupFor(Event childItem) {
//This is how the adapter determines what the headers are and what child items belong to it
return (Date) childItem.getDate().clone();
}
@Override
public View getChildView(LayoutInflater inflater, int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
//Inflate your view
//Gets the Event data for this view
Event event = getChild(groupPosition, childPosition);
//Fill view with event data
}
@Override
public View getGroupView(LayoutInflater inflater, int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
//Inflate your header view
//Gets the Date for this view
Date date = getGroup(groupPosition);
//Fill view with date data
}
@Override
public boolean hasAutoExpandingGroups() {
//This forces our group views (headers) to always render expanded.
//Even attempting to programmatically collapse a group will not work.
return true;
}
@Override
public boolean isGroupSelectable(int groupPosition) {
//This prevents a user from seeing any touch feedback when a group (header) is clicked.
return false;
}
}
날짜 (예 : 2016 년 12 월 1 일)를 헤더로 설정 한 작업 StickyHeaderListView 라이브러리를 사용했습니다.
https://github.com/emilsjolander/StickyListHeaders
날짜를 밀리 초 단위로 변환하고 [시간을 포함하지 않음] 헤더를 만드십시오.
@Override
public long getHeaderId(int position) {
return <date in millis>;
}
다음은 Antew의 상세하고 유용한 답변을 기반으로 한 샘플 프로젝트 이며 ListView
스크롤 성능을 향상시키기 위해 뷰 홀더를 통합하는 여러 헤더를 사용하여 구현합니다 .
이 프로젝트에서 발생하는 ListView
클래스 는 클래스 HeaderItem
또는 클래스의 인스턴스이며 RowItem
다 추상 클래스의 서브 클래스 Item
입니다. 의 각 클래스 Item
서브는 사용자 정의 어댑터의 다른보기 유형에 해당합니다 ItemAdapter
. 상기 방법 getView()
에 따라 ItemAdapter
발급되는 발급 getView()
방법 HeaderItem
또는 방법에 따라 RowItem
발급하는 방법 Item
에서 발급하는 getView()
방법. 각 서브 Item
클래스는 고유 한 한 뷰 홀더를 제공합니다.
뷰 홀더는 다음과 같이 구현됩니다. getView()
방법 on- Item
sub-클래스가 있는지 여부를 확인 View
받는 전달 된 object- getView()
에, 대한 방법은 널 ItemAdapter
이다. 확장 된 뷰 배치가 팽창되고 뷰가 인스턴스화되고 팽창 된 것과 다 View.setTag()
. View
객체가 null이 아닌이이 경우, 뷰 홀더 객체가 이미 뷰와 연관 되어 있고 뷰 홀더 가을 통해 검색됩니다 View.getTag()
. 뷰 홀더가 사용되는 방법은 다음 코드 스 니펫에서 볼 수 있습니다 HeaderItem
.
@Override
View getView(LayoutInflater i, View v) {
ViewHolder h;
if (v == null) {
v = i.inflate(R.layout.header, null);
h = new ViewHolder(v);
v.setTag(h);
} else {
h = (ViewHolder) v.getTag();
}
h.category.setText(text());
return v;
}
private class ViewHolder {
final TextView category;
ViewHolder(View v) {
category = v.findViewById(R.id.category);
}
}
ListView의 완전한 구현은 다음과 유연합니다. Java 코드는 다음과 달라집니다.
import android.app.ListActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class MainActivity extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ItemAdapter(getItems()));
}
class ItemAdapter extends ArrayAdapter<Item> {
final private List<Class<?>> viewTypes;
ItemAdapter(List<Item> items) {
super(MainActivity.this, 0, items);
if (items.contains(null))
throw new IllegalArgumentException("null item");
viewTypes = getViewTypes(items);
}
private List<Class<?>> getViewTypes(List<Item> items) {
Set<Class<?>> set = new HashSet<>();
for (Item i : items)
set.add(i.getClass());
List<Class<?>> list = new ArrayList<>(set);
return Collections.unmodifiableList(list);
}
@Override
public int getViewTypeCount() {
return viewTypes.size();
}
@Override
public int getItemViewType(int position) {
Item t = getItem(position);
return viewTypes.indexOf(t.getClass());
}
@Override
public View getView(int position, View v, ViewGroup unused) {
return getItem(position).getView(getLayoutInflater(), v);
}
}
abstract private class Item {
final private String text;
Item(String text) {
this.text = text;
}
String text() { return text; }
abstract View getView(LayoutInflater i, View v);
}
private class HeaderItem extends Item {
HeaderItem(String text) {
super(text);
}
@Override
View getView(LayoutInflater i, View v) {
ViewHolder h;
if (v == null) {
v = i.inflate(R.layout.header, null);
h = new ViewHolder(v);
v.setTag(h);
} else {
h = (ViewHolder) v.getTag();
}
h.category.setText(text());
return v;
}
private class ViewHolder {
final TextView category;
ViewHolder(View v) {
category = v.findViewById(R.id.category);
}
}
}
private class RowItem extends Item {
RowItem(String text) {
super(text);
}
@Override
View getView(LayoutInflater i, View v) {
ViewHolder h;
if (v == null) {
v = i.inflate(R.layout.row, null);
h = new ViewHolder(v);
v.setTag(h);
} else {
h = (ViewHolder) v.getTag();
}
h.option.setText(text());
return v;
}
private class ViewHolder {
final TextView option;
ViewHolder(View v) {
option = v.findViewById(R.id.option);
}
}
}
private List<Item> getItems() {
List<Item> t = new ArrayList<>();
t.add(new HeaderItem("Header 1"));
t.add(new RowItem("Row 2"));
t.add(new HeaderItem("Header 3"));
t.add(new RowItem("Row 4"));
t.add(new HeaderItem("Header 5"));
t.add(new RowItem("Row 6"));
t.add(new HeaderItem("Header 7"));
t.add(new RowItem("Row 8"));
t.add(new HeaderItem("Header 9"));
t.add(new RowItem("Row 10"));
t.add(new HeaderItem("Header 11"));
t.add(new RowItem("Row 12"));
t.add(new HeaderItem("Header 13"));
t.add(new RowItem("Row 14"));
t.add(new HeaderItem("Header 15"));
t.add(new RowItem("Row 16"));
t.add(new HeaderItem("Header 17"));
t.add(new RowItem("Row 18"));
t.add(new HeaderItem("Header 19"));
t.add(new RowItem("Row 20"));
t.add(new HeaderItem("Header 21"));
t.add(new RowItem("Row 22"));
t.add(new HeaderItem("Header 23"));
t.add(new RowItem("Row 24"));
t.add(new HeaderItem("Header 25"));
t.add(new RowItem("Row 26"));
t.add(new HeaderItem("Header 27"));
t.add(new RowItem("Row 28"));
t.add(new RowItem("Row 29"));
t.add(new RowItem("Row 30"));
t.add(new HeaderItem("Header 31"));
t.add(new RowItem("Row 32"));
t.add(new HeaderItem("Header 33"));
t.add(new RowItem("Row 34"));
t.add(new RowItem("Row 35"));
t.add(new RowItem("Row 36"));
return t;
}
}
각 항목 서브 클래스마다 하나씩 두 개의 목록 항목 레이아웃이 있습니다. header
HeaderItem에서 사용 하는 레이아웃은 다음과 같습니다 .
<?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="wrap_content"
android:background="#FFAAAAAA"
>
<TextView
android:id="@+id/category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:textColor="#FF000000"
android:textSize="20sp"
android:textStyle="bold"
/>
</LinearLayout>
다음은 row
RowItem에서 사용 하는 레이아웃입니다 .
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
>
<TextView
android:id="@+id/option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
/>
</LinearLayout>
다음은 결과 ListView의 일부 이미지입니다.
참고 URL : https://stackoverflow.com/questions/13590627/android-listview-headers
'IT' 카테고리의 다른 글
UITextField 활성화 색 (0) | 2020.07.11 |
---|---|
django 앱에 파비콘을 표시해야합니까? (0) | 2020.07.11 |
기본 소리 알림을 사용 하시겠습니까? (0) | 2020.07.11 |
임시 SSH 터널을 설정하기위한 Bash 펼쳐보기 (0) | 2020.07.11 |
“return list.sort ()”가 목록이 아닌 None을 반환하는 이유는 무엇입니까? (0) | 2020.07.11 |