You can fold the Gridview
Realize the principle of
1, folding implementation
Override the setAdapter method of the GridView
@Override
public void setAdapter(ListAdapter adapter) {
if (foldNm > 0) {
// Fold
adapter = new FoldViewGridAdapter(adapter, foldNm);
}
super.setAdapter(adapter);
}
Copy the code
FoldViewGridAdapter FoldViewGridAdapter is a wrapper class that implements the wrapping of the current Adapter, overriding the getCount method as follows:
private class FoldViewGridAdapter implements WrapperListAdapter {...@Override
public int getCount(a) {
// if fn is less than 1, it is not folded
if (fn < 0) {
return adapter.getCount();
} else {
// If fn is greater than 0, fold
if (expend) {
return adapter.getCount();
} else {
returnMath.min(adapter.getCount(), fn * getNumColumns()); }}}@Override
public ListAdapter getWrappedAdapter(a) {
return this; }... }Copy the code
The initial value of FN is -1, that is, it is not folded. When the fn value is greater than 0, the folding judgment needs to be performed. If the folding is required, the return is returned
return Math.min(adapter.getCount(), fn * getNumColumns());
Copy the code
The smallest of the two. Fn * getNumColumns() is the product of the number of rows displayed when folded and the number of columns displayed, i.e. the number of columns displayed.
2, How to add a ExpendControlView
The setAdapter method is also overridden to repackage the adapter.
HeaderViewGridAdapter headerViewGridAdapter = new HeaderViewGridAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
Copy the code
The logic for adding a ExpendControlView is mainly in the HeaderViewGridAdapter, which implements the following:
1, How to make the added ExpendControlView exclusive to a row
public void addExpendControlView(View v, Object data, boolean isSelectable, boolean isExpendControlView) {
ViewGroup.LayoutParams lyp = v.getLayoutParams();
FixedViewInfo info = new FixedViewInfo();
FrameLayout fl = new FullWidthFixedViewLayout(getContext());
if(lyp ! =null) {
v.setLayoutParams(new FrameLayout.LayoutParams(lyp.width, lyp.height));
fl.setLayoutParams(new LayoutParams(lyp.width, lyp.height));
}
fl.addView(v);
info.view = v;
info.viewContainer = fl;
info.data = data;
info.isSelectable = isSelectable;
// Control whether it can be folded
info.isExpendControlView = isExpendControlView;
mFooterViewInfos.add(info);
if(mAdapter ! =null) { ((HeaderViewGridAdapter) mAdapter).notifyDataSetChanged(); }}Copy the code
The addExpendControlView method creates an FL viewGroup and then adds the ControlView to the FL. FullWidthFixedViewLayout looks like this:
private class FullWidthFixedViewLayout extends FrameLayout {
public FullWidthFixedViewLayout(Context context) {
super(context);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int realLeft = GridViewEnableFooter.this.getPaddingLeft() + getPaddingLeft();
// Try to make where it should be, from left, full width
if(realLeft ! = left) { offsetLeftAndRight(realLeft - left); }super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int targetWidth = GridViewEnableFooter.this.getMeasuredWidth()
- GridViewEnableFooter.this.getPaddingLeft()
- GridViewEnableFooter.this.getPaddingRight();
widthMeasureSpec = MeasureSpec.makeMeasureSpec(targetWidth,
MeasureSpec.getMode(widthMeasureSpec));
super.onMeasure(widthMeasureSpec, heightMeasureSpec); }}Copy the code
Set the width to be the same as the GridView width on onLayout and onMeasure, and set the FL width to be the same as the GridView width.
2. Count calculation after adding ExpendControlView
Adding the ExpendControlView requires recalculating the getCount return value of the Adapter as follows:
public int getCount(a) {
return getExpendControlViewsCount() * mNumColumns + getAdapterAndPlaceHolderCount();
}
Copy the code
Because a ExpendControlView a line, so need to be multiplied by the number of columns, getAdapterAndPlaceHolderCount method is as follows:
private int getAdapterAndPlaceHolderCount(a) {
return (int) (Math.ceil(1f * mAdapter.getCount() / mNumColumns) * mNumColumns);
}
Copy the code
GetAdapterAndPlaceHolderCount used to replenish quantity, making the count number to an integer multiple of. If it is not an integer column, then the added ExpendControlView does not occupy a separate row, indicating a problem.
Rewrite the getView method.
The added ExpendControlView needs to be returned in getView, so you also need to override the getView method.
public View getView(int position, View convertView, ViewGroup parent) {
// Adapter
final int adjPosition = position - numHeadersAndPlaceholders;
int adapterCount = 0;
if(mAdapter ! =null) {
adapterCount = getAdapterAndPlaceHolderCount();
if (adjPosition < adapterCount) {
if (adjPosition < mAdapter.getCount()) {
return mAdapter.getView(adjPosition, convertView, parent);
} else {
if (convertView == null) {
convertView = new View(parent.getContext());
}
convertView.setVisibility(View.INVISIBLE);
convertView.setMinimumHeight(mRowHeight);
returnconvertView; }}}// ExpendControlView
final int footerPosition = adjPosition - adapterCount;
if (footerPosition < getCount()) {
View footViewContainer = mFooterViewInfos
.get(footerPosition / mNumColumns).viewContainer;
if (position % mNumColumns == 0) {
return footViewContainer;
} else {
if (convertView == null) {
convertView = new View(parent.getContext());
}
// We need to do this because GridView uses the height of the last item
// in a row to determine the height for the entire row.
convertView.setVisibility(View.INVISIBLE);
convertView.setMinimumHeight(footViewContainer.getHeight());
returnconvertView; }}throw new ArrayIndexOutOfBoundsException(position);
}
Copy the code
methods
1. Add bottom control View
public void addExpendControlView(View view)
Copy the code
2. Set the number of rows to display when folding
setFoldNum(int foldNm)
Copy the code
Used to set the number of rows to display when collapsing
Method of use
// Fold control View
gridView.addFooterView(LoadMoreView(this))
// Set the number of rows to collapse
gridView.setFoldNum(2) gridView.adapter = object : BaseAdapter() {... }Copy the code
LoadMoreView is the collapsible control view at the bottom. When adding your own control view, inherit the following interface
interface IExpendControl {
/** * expand */
fun expend(a)
/** ** fold */
fun fold(a)
}
Copy the code
Override the expend and fold methods, i.e., expand and fold, to complete the control.
class LoadMoreView @JvmOverloads constructor(
context: Context.attrs: AttributeSet? = null
) : ConstraintLayout(context, attrs), IExpendControl {
private var viewBinding: LoadMoreViewBinding =
LoadMoreViewBinding.inflate(LayoutInflater.from(context), this)
override fun expend(a) {
// Operate while expanding
viewBinding.loadMore.text = "Fold"
viewBinding.arrow.setImageResource(R.drawable.up_arrow)
}
override fun fold(a) {
// Operate while folding
viewBinding.loadMore.text = "Unfold all"
viewBinding.arrow.setImageResource(R.drawable.down_arrow)
}
}
Copy the code
The source address
Github.com/hankinghu/E…
reference
Github.com/liaohuqiu/a…