我有一个类可以将HeaderView添加到 RecyclerView 。它正在工作,但在视图的顶部添加了额外的不必要的空间。以下是代码段。我该如何删除这个空间?
public class HeaderDecoration extends RecyclerView.ItemDecoration {
private final View mView;
private final boolean mHorizontal;
private final float mParallax;
private final float mShadowSize;
private final int mColumns;
private final Paint mShadowPaint;
public HeaderDecoration(View view, boolean scrollsHorizontally, float parallax, float shadowSize, int columns) {
mView = view;
mHorizontal = scrollsHorizontally;
mParallax = parallax;
mShadowSize = shadowSize;
mColumns = columns;
if (mShadowSize > 0) {
mShadowPaint = new Paint();
mShadowPaint.setShader(mHorizontal ?
new LinearGradient(mShadowSize, 0, 0, 0,
new int[]{Color.argb(55, 0, 0, 0), Color.argb(55, 0, 0, 0), Color.argb(3, 0, 0, 0)},
new float[]{0f, .5f, 1f},
Shader.TileMode.CLAMP) :
new LinearGradient(0, mShadowSize, 0, 0,
new int[]{Color.argb(55, 0, 0, 0), Color.argb(55, 0, 0, 0), Color.argb(3, 0, 0, 0)},
new float[]{0f, .5f, 1f},
Shader.TileMode.CLAMP));
} else {
mShadowPaint = null;
}
}
public static Builder with(Context context) {
return new Builder(context);
}
public static Builder with(RecyclerView recyclerView) {
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
GridLayoutManager manager = (GridLayoutManager) layoutManager;
return new Builder(recyclerView.getContext(), manager.getSpanCount());
} else if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager manager = (LinearLayoutManager) layoutManager;
return new Builder(recyclerView.getContext(), manager.getOrientation() == LinearLayoutManager.HORIZONTAL);
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
StaggeredGridLayoutManager manager = (StaggeredGridLayoutManager) layoutManager;
return new Builder(recyclerView.getContext(), manager.getSpanCount());
} else {
return new Builder(recyclerView.getContext());
}
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
// layout basically just gets drawn on the reserved space on top of the first view
mView.layout(parent.getLeft(), 0, parent.getRight(), mView.getMeasuredHeight());
for (int i = 0; i < parent.getChildCount(); i++) {
View view = parent.getChildAt(i);
if (parent.getChildAdapterPosition(view) == 0) {
c.save();
if (mHorizontal) {
c.clipRect(parent.getLeft(), parent.getTop(), view.getLeft(), parent.getBottom());
final int width = mView.getMeasuredWidth();
final float left = (view.getLeft() - width) * mParallax;
c.translate(left, 0);
mView.draw(c);
if (mShadowSize > 0) {
c.translate(view.getLeft() - left - mShadowSize, 0);
c.drawRect(parent.getLeft(), parent.getTop(), mShadowSize, parent.getBottom(), mShadowPaint);
}
} else {
c.clipRect(parent.getLeft(), parent.getTop(), parent.getRight(), view.getTop());
final int height = mView.getMeasuredHeight();
final float top = (view.getTop() - height) * mParallax;
c.translate(0, top);
mView.draw(c);
if (mShadowSize > 0) {
c.translate(0, view.getTop() - top - mShadowSize);
c.drawRect(parent.getLeft(), parent.getTop(), parent.getRight(), mShadowSize, mShadowPaint);
}
}
c.restore();
break;
}
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (parent.getChildAdapterPosition(view) < mColumns) {
if (mHorizontal) {
if (mView.getMeasuredWidth() <= 0) {
mView.measure(View.MeasureSpec.makeMeasureSpec(parent.getMeasuredWidth(), View.MeasureSpec.AT_MOST),
View.MeasureSpec.makeMeasureSpec(parent.getMeasuredHeight(), View.MeasureSpec.AT_MOST));
}
outRect.set(mView.getMeasuredWidth(), 0, 0, 0);
} else {
if (mView.getMeasuredHeight() <= 0) {
mView.measure(View.MeasureSpec.makeMeasureSpec(parent.getMeasuredWidth(), View.MeasureSpec.AT_MOST),
View.MeasureSpec.makeMeasureSpec(parent.getMeasuredHeight(), View.MeasureSpec.AT_MOST));
}
outRect.set(0, mView.getMeasuredHeight(), 0, 0);
}
} else {
outRect.setEmpty();
}
}
public static class Builder {
private Context mContext;
private View mView;
private boolean mHorizontal;
private float mParallax = 1f;
private float mShadowSize;
private int mColumns = 1;
public Builder(@NonNull Context context) {
mContext = context;
}
public Builder(@NonNull Context context, @IntRange(from = 1) int columns) {
mContext = context;
mColumns = columns;
}
public Builder(@NonNull Context context, boolean horizontal) {
mContext = context;
mHorizontal = horizontal;
}
public Builder setView(@NonNull View view) {
mView = view;
return this;
}
public Builder inflate(@LayoutRes int layoutRes) {
mView = LayoutInflater.from(mContext).inflate(layoutRes, null, false);
return this;
}
/**
* Adds a parallax effect.
*
* @param parallax the multiplier to use, 0f would be the view standing still, 1f moves along with the first item.
* @return this builder
*/
public Builder parallax(@FloatRange(from = 0f, to = 1f) float parallax) {
mParallax = parallax;
return this;
}
public Builder scrollsHorizontally(boolean isHorizontal) {
mHorizontal = isHorizontal;
return this;
}
public Builder dropShadowDp(@IntRange(from = 0, to = 80) int dp) {
mShadowSize = mContext.getResources().getDisplayMetrics().density * dp;
return this;
}
public Builder dropShadow(@DimenRes int dimenResource) {
mShadowSize = mContext.getResources().getDimensionPixelSize(dimenResource);
return this;
}
public HeaderDecoration build() {
if (mView == null) {
throw new IllegalStateException("View must be set with either setView or inflate");
}
return new HeaderDecoration(mView, mHorizontal, mParallax, mShadowSize * 1.5f, mColumns);
}
public Builder columns(@IntRange(from = 1) int columns) {
mColumns = columns;
return this;
}
}
}
并使用此课程如下
recyclerView.addItemDecoration(HeaderDecoration.with(recyclerView)
.setView(getActivity().getLayoutInflater().inflate(R.layout.inflate_header_view_chat, null, false))
.dropShadowDp(0)
.build());
chatAdapter = new ChatAdapter(getActivity(), postGroupData, this, mTotalRecords, this);
recyclerView.setAdapter(chatAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setOnTouchListener(this);
chatAdapter.setOnItemClickListener(this);
recyclerView.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/toolbar"
layout="@layout/tool_bar_view_white" />
<View
android:id="@+id/viewTop"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/toolbar"
android:background="#BFBFBF" />
<com.sis.rockeit.widgets.TypefaceTextView
android:id="@+id/load_more"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/toolbar"
android:background="@color/md_blue_grey_300"
android:gravity="center"
android:padding="10dp"
android:text="@string/loading_more_items"
android:textColor="@color/colorAccent2"
android:visibility="gone" />
<com.sis.rockeit.widgets.TypefaceTextView
android:id="@+id/updating"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/toolbar"
android:background="@color/md_blue_grey_300"
android:gravity="center"
android:padding="10dp"
android:text="@string/updating"
android:textColor="@color/colorAccent2"
android:visibility="gone" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/relativeLayout"
android:layout_below="@+id/viewTop">
<include
android:id="@+id/headerView"
layout="@layout/inflate_header_view_chat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<android.support.v7.widget.RecyclerView xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list"
android:name="com.sis.rockeit.views.fragments.ChatFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/attachmentPreview"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/headerView"
android:layout_marginEnd="@dimen/global_padding"
android:layout_marginLeft="@dimen/global_padding"
android:layout_marginRight="@dimen/global_padding"
android:layout_marginStart="@dimen/global_padding"
app:layoutManager="LinearLayoutManager"
tools:context=".fragments.ChatFragment" />
<RelativeLayout
android:id="@+id/attachmentPreview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/headerView"
android:background="@drawable/attachement_background">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerViewChatPreview"
android:layout_width="match_parent"
android:layout_height="@dimen/attachmentViewHeightChat" />
</RelativeLayout>
<include
layout="@layout/inflate_attachment_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="visible" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/mdtp_white">
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CFCFCD" />
<ImageView
android:id="@+id/imgAttachFilesChat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="5dp"
android:src="@drawable/add_attach" />
<com.sis.rockeit.widgets.TypefaceTextView
android:id="@+id/txtSendReply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/view"
android:layout_centerVertical="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="10dp"
android:text="Send"
android:textColor="@color/rockeit_orange_color"
app:fontName="@string/lato_medium" />
<com.sis.rockeit.widgets.TypefaceEditText
android:id="@+id/editChatText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/view"
android:layout_margin="10dp"
android:layout_toEndOf="@+id/imgAttachFilesChat"
android:layout_toLeftOf="@+id/txtSendReply"
android:layout_toRightOf="@+id/imgAttachFilesChat"
android:layout_toStartOf="@+id/txtSendReply"
android:background="@drawable/text_box"
android:maxLines="3"
android:padding="5dp"
android:text=""
android:textColor="@color/colorAccent2"
android:textSize="@dimen/text_size_chat_bottom"
app:fontName="@string/lato_medium" />
</RelativeLayout>
</RelativeLayout>
header.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/global_padding">
<ImageView
android:id="@+id/imgUser"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/ic_profile" />
<com.sis.rockeit.widgets.TypefaceTextView
android:id="@+id/textUserName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/welcome_text_margin_top"
android:text="Hi, David here!"
android:textColor="@color/colorAccent2"
android:textSize="24sp"
app:fontName="@string/lato_black" />
<com.sis.rockeit.widgets.TypefaceTextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I would be happy to answer your questions."
android:textColor="@color/colorAccent2"
android:textSize="@dimen/welcome_msg_secondary_text_size"
app:fontName="@string/lato_regular" />
答案 0 :(得分:1)
使用下面的代码添加装饰器类。
private class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpacesItemDecoration(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if(parent.getChildAdapterPosition(view) == state.getItemCount()-1){
outRect.bottom = space;
outRect.top = 0; //don't forget about recycling...
}
if(parent.getChildAdapterPosition(view) == 0){
outRect.top = space;
outRect.bottom = 0;
}
}
}
将上面的类附加到装饰器视图。
int space = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
getResources().getDisplayMetrics());
recyclerView.addItemDecoration(new SpacesItemDecoration(space));