所以我有以下观点
list_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layoutSessionItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/lblGroupDate"
style="@style/CustomText.GrayTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/lblCourseCode"
style="@style/CustomText.GrayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/lblSessionCode"
style="@style/CustomText.GrayText"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
所以基本上我从数据库中获得以下数据:
COURSE_CODE
SESSION_CODE
SESSION_DATE
我需要按SESSION_DATE对ListView项进行分组,我要做的是保留一个名为“PreviousDate”的变量,并将其与当前的SESSION_DATE进行比较,如果它不同,那么我启用带有ID的标头:“lblGroupDate”if日期是相同的我隐藏“lblGroupDate”。
这是我的适配器:
public class SessionListAdapter extends BaseAdapter {
private Date PreviousDate = new Date();
static class ViewHolder {
TextView lblGroupDate;
TextView lblCourseCode;
TextView lblSessionCode;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.list_view_item, null);
holder = new ViewHolder();
holder.lblGroupDate = (TextView) convertView.findViewById(R.id.lblGroupDate);
holder.lblCourseCode = (TextView) convertView.findViewById(R.id.lblCourseCode);
holder.lblSessionCode = (TextView) convertView.findViewById(R.id.lblSessionCode);
} else {
holder = (ViewHolder)convertView.getTag();
}
SessionData session = (SessionData) getItem(position);
if(session != null) {
Date sessionDate = session.SESSION_DATE;
if (!mPrevDate.equals(sessionDate)) {
PreviousDate = sessionDate;
// HIDE GROUP HEADER
holder.lblGroupDate.setVisibility(View.GONE);
}
else {
// SHOW GROUP HEADER
holder.lblGroupDate.setVisibility(View.VISIBLE);
}
holder.lblCourseCode.setText(session.COURSE_CODE);
holder.lblSessionCode.setText(session.SESSION_CODE);
}
}
}
这是问题:
假设我有20条记录,当我向下滚动然后再次向上滚动时,启用了Group Header(lblGroupDate)的行在没有标题的情况下向上移动,标题被移动到接下来的3行。为什么会这样?
答案 0 :(得分:1)
这种情况正在发生,因为getView()可以随时从您的数据集中无序调用。您需要创建可以支持适配器的数据集。只需将适配器分类。稍后将用代码更新答案。
<强> SessionListAdapter.java 强>
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.content.Context;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class SessionListAdapter extends BaseAdapter
{
private static final int TYPE_GROUP = 0;
private static final int TYPE_SESSION = 1;
private static final int MAX_TYPES = 2;
private final LayoutInflater mLayoutInflater;
private ArrayList<SessionViewData> mData;
public SessionListAdapter(Context context, List<SessionData> sessionData)
{
mLayoutInflater = LayoutInflater.from(context);
updateSessionViewData(sessionData);
}
public void updateSessionViewData(List<SessionData> sessionData)
{
Date previousDate = new Date();
ArrayList<SessionViewData> data = new ArrayList<SessionViewData>();
for(SessionData session: sessionData){
if(!previousDate.equals(session.SESSION_DATE)){
data.add(new SessionViewData(TYPE_GROUP, session));
previousDate = session.SESSION_DATE;
}
data.add(new SessionViewData(TYPE_SESSION, session));
}
mData = data;
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
SessionViewData data = mData.get(position);
if(convertView == null){
final int layoutId;
switch(data.type){
case TYPE_GROUP: layoutId = R.layout.list_session_group; break;
case TYPE_SESSION: layoutId = R.layout.list_session_item; break;
default:
throw new IllegalArgumentException("Bad type for: " + data.session);
}
convertView = mLayoutInflater.inflate(layoutId, parent, false);
}
switch(data.type){
case TYPE_GROUP:
TextView lblGroupDate = ((TextView)convertView.findViewById(R.id.lblGroupDate));
lblGroupDate.setText(DateUtils.formatDateTime(convertView.getContext(),
data.session.SESSION_DATE.getTime(), DateUtils.FORMAT_SHOW_DATE));
break;
case TYPE_SESSION:
TextView lblCourseCode = (TextView)convertView.findViewById(R.id.lblCourseCode);
lblCourseCode.setText(data.session.COURSE_CODE);
TextView lblSessionCode = (TextView)convertView.findViewById(R.id.lblSessionCode);
lblSessionCode.setText(data.session.SESSION_CODE);
break;
}
return convertView;
}
@Override
public Object getItem(int position)
{
return mData.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public int getItemViewType(int position)
{
return mData.get(position).type;
}
@Override
public int getViewTypeCount()
{
return MAX_TYPES;
}
@Override
public int getCount()
{
return mData.size();
}
static class SessionViewData
{
int type;
SessionData session;
public SessionViewData(int type, SessionData session)
{
this.type = type;
this.session = session;
}
}
}
<强> list_session_group.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lblGroupDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/CustomText.GrayTitle"
/>
<强> list_session_item.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layoutSessionItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/lblCourseCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/CustomText.GrayText"
/>
<TextView
android:id="@+id/lblSessionCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/CustomText.GrayText"
/>
</LinearLayout>