【问题标题】:How to add sticky header in listview with background image on list row in android?如何在列表视图中添加粘性标题,并在 android 的列表行中添加背景图像?
【发布时间】:2014-05-21 12:10:15
【问题描述】:

我正在尝试在列表视图中添加粘性标题。我在https://github.com/beworker/pinned-section-listview找到的代码的帮助下实现了这一点

下面是我将列表视图行设为的图片

它工作正常,但我需要自定义上面的行。单行有两个单独的布局,它们是 a.) listheader.xml b.) listrow.xml 这两个 xml 都是 listview 单行的两个独立部分。

现在我想做的是列表行标题应该是透明背景(listheader.xml),而listrow.xml不应该有一个拿着相机的人的背景图像。图像应设置为每个列表视图行的背景。如下所示

所以我的列表视图行将有一个背景图像和一个标题,而不是在图像上方,而是在图像上方,如上图所示。 谁能告诉我我该怎么做。 下面是我使用的适配器代码。

public abstract class SectionAdapter extends BaseAdapter implements
        OnItemClickListener {

    private int mCount = -1;

    Context context;

    public SectionAdapter(Context c) {
        this.context = c;
        // TODO Auto-generated constructor stub
    }

    public abstract int numberOfSections();

    public abstract int numberOfRows(int section);

    public abstract View getRowView(int section, int row, View convertView,
            ViewGroup parent);

    public abstract Object getRowItem(int section, int row);

    public boolean hasSectionHeaderView(int section) {
        return false;
    }

    public View getSectionHeaderView(int section, View convertView,
            ViewGroup parent) {
        return null;
    }

    public Object getSectionHeaderItem(int section) {
        return null;
    }

    public int getRowViewTypeCount() {
        return 1;
    }

    public int getSectionHeaderViewTypeCount() {
        return 0;
    }

    /**
     * Must return a value between 0 and getRowViewTypeCount() (excluded)
     */
    public int getRowItemViewType(int section, int row) {
        return 0;
    }

    /**
     * Must return a value between 0 and getSectionHeaderViewTypeCount()
     * (excluded, if > 0)
     */
    public int getSectionHeaderItemViewType(int section) {
        return 0;
    }

    @Override
    /**
     * Dispatched to call onRowItemClick
     */
    public final void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {
        onRowItemClick(parent, view, getSection(position),
                getRowInSection(position), id);
    }

    public void onRowItemClick(AdapterView<?> parent, View view, int section,
            int row, long id) {

    }

    @Override
    /**
     * Counts the amount of cells = headers + rows
     */
    public final int getCount() {
        if (mCount < 0) {
            mCount = numberOfCellsBeforeSection(numberOfSections());
        }
        return mCount;
    }

    @Override
    public boolean isEmpty() {
        return getCount() == 0;
    }

    @Override
    /**
     * Dispatched to call getRowItem or getSectionHeaderItem
     */
    public final Object getItem(int position) {
        int section = getSection(position);
        if (isSectionHeader(position)) {
            if (hasSectionHeaderView(section)) {
                return getSectionHeaderItem(section);
            }
            return null;
        }
        return getRowItem(section, getRowInSection(position));
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    /**
     * Dispatched to call getRowView or getSectionHeaderView
     */
    public final View getView(int position, View convertView, ViewGroup parent) {

        /*
         * RelativeLayout rl = new RelativeLayout(context); LayoutParams
         * listParams = new LayoutParams(LayoutParams.MATCH_PARENT,
         * LayoutParams.MATCH_PARENT); rl.setLayoutParams(listParams);
         * convertView = (View)rl;
         */

        int section = getSection(position);
        if (isSectionHeader(position)) {
            if (hasSectionHeaderView(section)) {
                return getSectionHeaderView(section, convertView, parent);
            }
            return null;
        }
        return getRowView(section, getRowInSection(position), convertView,
                parent);
        // return convertView;
    }

    /**
     * Returns the section number of the indicated cell
     */
    protected int getSection(int position) {
        int section = 0;
        while (numberOfCellsBeforeSection(section) <= position) {
            section++;
        }
        return section - 1;
    }

    /**
     * Returns the row index of the indicated cell Should not be call with
     * positions directing to section headers
     */
    protected int getRowInSection(int position) {
        int section = getSection(position);
        int row = position - numberOfCellsBeforeSection(section);
        if (hasSectionHeaderView(section)) {
            return row - 1;
        } else {
            return row;
        }
    }

    /**
     * Returns true if the cell at this index is a section header
     */
    protected boolean isSectionHeader(int position) {
        int section = getSection(position);
        return hasSectionHeaderView(section)
                && numberOfCellsBeforeSection(section) == position;
    }

    /**
     * Returns the number of cells (= headers + rows) before the indicated
     * section
     */
    protected int numberOfCellsBeforeSection(int section) {
        int count = 0;
        for (int i = 0; i < Math.min(numberOfSections(), section); i++) {
            if (hasSectionHeaderView(i)) {
                count += 1;
            }
            count += numberOfRows(i);
        }
        return count;
    }

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
        mCount = numberOfCellsBeforeSection(numberOfSections());
    }

    @Override
    public void notifyDataSetInvalidated() {
        super.notifyDataSetInvalidated();
        mCount = numberOfCellsBeforeSection(numberOfSections());
    }

    @Override
    /**
     * Dispatched to call getRowItemViewType or getSectionHeaderItemViewType
     */
    public final int getItemViewType(int position) {
        int section = getSection(position);
        if (isSectionHeader(position)) {
            return getRowViewTypeCount()
                    + getSectionHeaderItemViewType(section);
        } else {
            return getRowItemViewType(section, getRowInSection(position));
        }
    }

    @Override
    /**
     * Dispatched to call getRowViewTypeCount and getSectionHeaderViewTypeCount
     */
    public final int getViewTypeCount() {
        return getRowViewTypeCount() + getSectionHeaderViewTypeCount();
    }

    @Override
    /**
     * By default, disables section headers
     */
    public boolean isEnabled(int position) {
        return !isSectionHeader(position);
    }
}

【问题讨论】:

  • 尝试使用 framelayout 或 relativelayout
  • 能否请您详细说明如何使用框架布局或相对布局
  • 如果第二张图片中的整个内容只是列表中的一项,为什么不为其项目创建一个带有单个 xml 的自定义列表视图?然后在您的自定义适配器中,您将所有这些信息和图片设置在它们的位置。

标签: android sticky


【解决方案1】:

问题

  • 您希望您的 listheader.xml 位于 listview 之上
  • 您希望 listView 上的每个项目都有自己的背景

解决方案

  1. 要将您的listheader.xml 放在listView 之上,您应该在您的main activity 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" >
    
    
      <include
        android:id="@+id/listheader"
        android:layout_alignParentTop="true"
        layout="@layout/listheader" />
      . <!-- dont forget your listheader.xml should have transparent background -->
    
      <ListView
        android:id="@+id/yourList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:divider="@android:color/transparent" >
      </ListView>
    
    </RelativeLayout>
    
  2. 要将background 设置为您的列表视图items,您应该这样做:

     public final View getView(int position, View convertView, ViewGroup parent) {
    
    
      /**
       * I didnt have time to study your code about what happens here,
       * but I know the possible solution that you should be implemented here :)
       * Here I will post the code that puts background 
       * to listView row at this position as shown
       * in your image. So here you put your conditions for your 
       * rows that are the same as in the image above that you have shown
       * */
    
        if( /* put the your conditions here so that the row would be the same as in the image */ ){
         LayoutInflater inflater = (LayoutInflater) context.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rowView = inflater.inflate(R.layout.listrow, null); // this is your listrow.xml
          // i guess your xml has as root element a relative layout
          RelativeLayout rLayout = (RelativeLayout) rowView .findViewById (R.id.rLayout);
           Resources res = contetx.getResources(); //resource handle
            Drawable drawable = res.getDrawable(R.drawable.newImage);// here you put your image that you want for each row based on your row position or whatever your condition is
    
          rLayout.setBackgroundDrawable(drawable);
        }
    
      }
    

【讨论】:

    【解决方案2】:

    我认为您需要添加另一个布局文件,例如 listrowitem.xmlRelativeLayout,您将在其中将您的 listheader.xml 放在 listrow.xml 之上。之后,您可以将您的listheader 设置为@null 背景。

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 2018-12-23
      • 2015-02-05
      • 1970-01-01
      • 2012-12-22
      • 2020-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多