How to add sticky header in listview with backgrou

2019-02-19 07:20发布

I am trying to add sticky header in listview. I implemented that with the help of code which I found at https://github.com/beworker/pinned-section-listview

Below is the picture in which I got the listview row as enter image description here

Its working fine but I need to customize above row. there are two separate layout for a single row which are a.) listheader.xml b.) listrow.xml both the xml are two separate parts of a single row of listview.

Now what I want to do is that list row header should be with transparent background(listheader.xml) and listrow.xml should not have the background image of a guy carrying camera. the image should be set to background of each listview row. which will look like below enter image description here

so my listview row will have a background image and a header not above image but over the image as you can see in the above image. can anybody tell me how can I do that. below is my code of adapter I used.

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

2条回答
兄弟一词,经得起流年.
2楼-- · 2019-02-19 08:07

I think you need to add another layout file, say listrowitem.xml with RelativeLayout where you will put your listheader.xml on top of listrow.xml. After that, you can make your listheader to have @null background.

查看更多
Summer. ? 凉城
3楼-- · 2019-02-19 08:08

Problem

  • You want your listheader.xml to be on top of listview
  • You want that each item on listView to have its own background

Solution

  1. To bring your listheader.xml on top of listView you should do something like this in your 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. To set background to your list view items you should do this:

     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);
        }
    
      }
    
查看更多
登录 后发表回答