android - 在带有标题的 ListView 中实现 StickyListHeader

标签 android android-listview

我有一个 ListView,它有 2 种类型的 header ,我想在其中实现另一种类型的 header ,称为 StickyListHeader

好吧,实现 2 种类型的 header 对我来说是一项复杂的任务,现在实现 StickyListHeader 并不是一件容易的事。让我必须为每第 5 个 View 添加一个 StickyListHeader。

这是代码:

public class ContentsFragment extends ListFragment  implements OnTouchListener,AbsListView.OnScrollListener {

private MyCustomAdapter mAdapter;
Activity temp = getActivity();

String []s = new String[500];
ArrayList<GS> q = new ArrayList<GS>();
ListView lv;
int count=0;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

DBAdapter db = DBAdapter.getDBAdapter(getActivity());

if (!db.checkDatabase())   
    db.createDatabase(getActivity());

db.openDatabase();

q = db.getData();

mAdapter = new MyCustomAdapter(getActivity());

mAdapter.addSeparatorItem(new ContentWrapper(q.get(0).getA_name(),null,null));
mAdapter.addItem(new ContentWrapper(q.get(0).getAS_name(), q.get(0).getDesc_art(),null));


for (int i = 1; i <= 14; i++) {
if (!(q.get(i).getA_name().trim().equals(q.get(i-1).getA_name().trim()))) {

  mAdapter.addSeparatorItem(new ContentWrapper(q.get(i).getA_name(), null,null));
}
if(!(q.get(i).getExtra()==null))
  mAdapter.addGraySeparatorItem(new ContentWrapper(q.get(i).getExtra(),null,null));

mAdapter.addItem(new ContentWrapper(q.get(i).getAS_name(), q.get(i).getDesc_art(),null));
}

for (int i = 15; i < 36; i++) {
  if (!(q.get(i).getA_name().trim().equals(q.get(i-1).getA_name().trim()))) {

      mAdapter.addSeparatorItem(new ContentWrapper(q.get(i).getA_name(), null,null));

  }
  if(!(q.get(i).getExtra()==null))
      mAdapter.addGraySeparatorItem(new ContentWrapper(q.get(i).getExtra(),null,null));


  mAdapter.addItem(new ContentWrapper(q.get(i).getAS_name(), q.get(i).getDesc_art(),null));

    }
//Adapter Class
private class MyCustomAdapter extends BaseAdapter {

private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_GRAY_SEPARATOR = 2;
private static final int TYPE_MAX_COUNT = TYPE_GRAY_SEPARATOR + 1;

private TreeSet<Integer> mGraySeparatorsSet = new TreeSet<Integer>();

private ArrayList<ContentWrapper> mData = new ArrayList<ContentWrapper>();
private LayoutInflater mInflater;

private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();

public MyCustomAdapter(Context context)
{
    mInflater = LayoutInflater.from(context); 
}

public void addItem(ContentWrapper value) {
    mData.add(value);
    notifyDataSetChanged();
}

public void addSeparatorItem(ContentWrapper value) {
    mData.add(value);
    // save separator position
    mSeparatorsSet.add(mData.size() - 1);
    notifyDataSetChanged();
}

public void addGraySeparatorItem(ContentWrapper value) {
    mData.add(value);
    // save separator position
    mGraySeparatorsSet.add(mData.size() - 1);
    notifyDataSetChanged();
}   


public ContentWrapper getItem(int position) {
    return mData.get(position);
}
@Override
public int getItemViewType(int position) {
    int viewType = TYPE_ITEM;
    if(mSeparatorsSet.contains(position))
       viewType = TYPE_SEPARATOR;
    else if(mGraySeparatorsSet.contains(position)) {
       viewType = TYPE_GRAY_SEPARATOR; 
    }

    return viewType;
    // return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}

@Override
public int getViewTypeCount() {
    return TYPE_MAX_COUNT;
}

public int getCount() {
    return mData.size();
}

public long getItemId(int position) {
    Log.v("getItemId Position", ""+position);
    return position;

}

public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    int type = getItemViewType(position);
    if (convertView == null) {
        holder = new ViewHolder();
        switch (type) {
        case TYPE_ITEM:
            convertView = mInflater.inflate(R.layout.white, null);
            holder.textView = (TextView)convertView.findViewById(R.id.text);
            break;
        case TYPE_SEPARATOR:
            convertView = mInflater.inflate(R.layout.black, null);
            holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
            break;
        case 2:
            convertView = mInflater.inflate(R.layout.gray, null);
            holder.textView = (TextView)convertView.findViewById(R.id.textViewGray);
            break;

        }
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder)convertView.getTag();
    } holder.textView.setText(mData.get(position).getItem());

    getListView().setFastScrollEnabled(true);
    if (type == TYPE_ITEM) {
        holder.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                    builder.setIcon(R.drawable.ic_launcher);
                    final String title = mData.get(position).getItem();
                    builder.setTitle(title);
                    builder.setMessage(mData.get(position).getItemDescription());
                    builder.setCancelable(false);
                    builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    });
                    AlertDialog alertDialog = builder.create();
                    alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
                        @Override
                        public void onShow(DialogInterface dialog) {
                            AlertDialog alertDialog = (AlertDialog) dialog;
                            ViewGroup viewGroup = (ViewGroup) alertDialog.getWindow()
                                    .getDecorView();
                            TextView textView = findTextViewWithTitle(viewGroup, title);
                            if (textView != null) {
                                textView.setEllipsize(null);
                                textView.setMaxHeight((int) (100 * alertDialog.getContext().getResources().getDisplayMetrics().density)); 
                                textView.setMovementMethod(new ScrollingMovementMethod());
                            }
                        }
                    });
                    alertDialog.show();
                }

                private TextView findTextViewWithTitle(ViewGroup viewGroup, String title) {
                    for (int i = 0, N = viewGroup.getChildCount(); i < N; i++) {
                        View child = viewGroup.getChildAt(i);
                        if (child instanceof TextView) {
                            TextView textView = (TextView) child;
                            if (textView.getText().equals(title)) {
                                return textView;
                            }
                        } else if (child instanceof ViewGroup) {
                            ViewGroup vGroup = (ViewGroup) child;
                            return findTextViewWithTitle(vGroup, title);
                        }
                    }
                    return null;
                }


            });
    }else if(type == 1) {
        holder.textView.setOnClickListener(null);
    }
    else
    {
        holder.textView.setOnClickListener(null);
    }

return convertView;
}
}
public static class ViewHolder {
public TextView textView;
public TextView header;
 int previousTop = 0;
}

public boolean onTouch(View v, MotionEvent event) {
return false;
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
    int visibleItemCount, int totalItemCount) { 
//the listview has only few children (of course according to the height of each child) who are visible
for(int i=0; i < getListView().getChildCount(); i++){
    View child = getListView().getChildAt(i);
    ViewHolder holder = (ViewHolder) child.getTag();

    //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();
    }
}   
}
}

如您所见,我为 StickyListHeader 实现了 onScroll() 方法。

现在我认为修改必须在类 MyCustomAdapter 构造函数和 getView() 方法中完成,因为我正在关注这个 example & 它声明我们必须处理构造函数,getView() 和 onScroll()。

谁能告诉我应该修改什么才能完成我的任务。

谢谢

最佳答案

对于页眉 ListView ,您应该使用 HeaderListView或者 PinnedHeaderListView库。非常易于使用。

关于android - 在带有标题的 ListView 中实现 StickyListHeader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23978315/

相关文章:

android - 如何在 ActionBarSherlock 的标题上设置 shadowColor?

android - 在 Android 列表中显示不同类型的行

android - 如何在 main.xml 中插入 list.xml 文件

android - AlphabetIndexer setCursor 不更新其缓存

android - 如何用jsoup解析图片

android - 在 Android 的 Mono 上单击 TextView 时显示键盘

android - Windows 资源管理器中未显示自定义相机照片

android - 如何从我的Android项目中删除lazyconfigurationusagecontext?

android - 如何修复我的布局位置错误?

java - 在 ListView 中限制项目