拖动n移动-即使在RecyclerView中只有少数项目,如何避免RecyclerView背景填满整个屏幕 [英] Drag-n-Move - How to avoid RecyclerView background fill the entire screen even there's only a few items in RecyclerView
问题描述
当前,我正在根据
我希望在移动项目时具有 RecycleView
的背景可见.
这是我所做的更改
-
将
RecycleView
背景颜色设置为红色-recyclerView.setBackgroundColor(Color.RED);
-
在该项目上提供纯白色.
< TextViewandroid:id ="@ + id/text"android:layout_width ="wrap_content"android:layout_height ="wrap_content"android:layout_gravity ="center_vertical"android:layout_marginLeft ="@ dimen/activity_horizontal_margin"android:textAppearance =?android:attr/textAppearanceMedium"/>< ImageViewandroid:id ="@ + id/handle"android:layout_width =?listPreferredItemHeight"android:layout_height ="match_parent"android:layout_gravity ="center_vertical | right"android:scaleType ="center"android:src ="@ drawable/ic_reorder_grey_500_24dp"/>
这是我想要的结果.
但是,有1个缺点.那时, RecyclerView
中只有几个项目.这些空白区域也将填充背景色.请看下面的截图.下面的 RecyclerView
仅包含3个项目.
我曾尝试使 RecyclerView
的高度 wrap_content
recyclerView.setLayoutParams(新的FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.WRAP_CONTENT));
但是,没关系.
如果 RecyclerView
长于屏幕上分配给它的区域,则没有问题:只需设置 RecyclerView
变为红色.但是,如果 RecyclerView
中的项目没有填满布局中分配给 RecyclerView
的空间,那么您会在空白处看到红色背景.这就是您要消除的东西.
为此,请在 RecyclerView
上设置一个 OnGlobalLayoutListener
,然后检查是否有多余的空间.如果没有多余的空间,则只需将背景色设置为红色;否则,将背景色设置为红色.否则,请创建一个 BitmapDrawable
,该代码用红色填充并适当调整大小,以仅为屏幕上的项目提供背景,并且不大到溢出到多余区域的范围.
这是您提到的项目的 RecyclerListFragment
中实现此目的的代码.
@Nullable@Override公共视图onCreateView(LayoutInflater充气器,ViewGroup容器,捆绑的saveInstanceState){最终的RecyclerView recyclerView = new RecyclerView(container.getContext());recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){@Overridepublic void onGlobalLayout(){recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);如果(recyclerView.getChildCount()== 0){返回;}int lastChildBottom = recyclerView.getChildAt(recyclerView.getChildCount()-1).getBottom();如果(lastChildBottom> = recyclerView.getHeight()){recyclerView.setBackgroundColor(Color.RED);返回;}位图位图= Bitmap.createBitmap(recyclerView.getWidth(),lastChildBottom,Bitmap.Config.ARGB_8888);bitmap.eraseColor(Color.RED);BitmapDrawable d =新的BitmapDrawable(getResources(),位图);d.setGravity(Gravity.TOP);recyclerView.setBackground(d);recyclerView.invalidate();}});返回recyclerView;}
以下是效果的视频:
如果实现了轻扫/移除手势,则在删除项目时还必须调用侦听器.我还必须在 RecyclerListAdapter
的 onItemClear()
中将背景色设置为非零值.
一种更简单的方法是定义一个可绘制对象,该对象可设置为仅在项目视图后面绘制的 RecyclerView
的背景.
公共类RecyclerViewBackground扩展了Drawable {私人RecyclerView mRecyclerView;私有位图mBitmap;私人Paint mPaint;RecyclerViewBackground(){极好的();mPaint = new Paint();mPaint.setColor(Color.RED);}@Override公共无效抽奖(画布画布){如果(mRecyclerView.getChildCount()== 0){返回;}int bottom = mRecyclerView.getChildAt(mRecyclerView.getChildCount()-1).getBottom();如果(底部> = mRecyclerView.getHeight()){底部= mRecyclerView.getHeight();}canvas.drawRect(0,0,canvas.getWidth(),bottom,mPaint);}@Override公共无效setAlpha(int alpha){}@Override公共无效setColorFilter(ColorFilter colorFilter){}@Overridepublic int getOpacity(){返回PixelFormat.OPAQUE;}公共无效的attachRecyclerView(RecyclerView recyclerView){mRecyclerView = recyclerView;}}
将此 Drawable
附加到 RecyclerView
上,如下所示:
RecyclerViewBackground bg = new RecyclerViewBackground();bg.attachRecyclerView(recyclerView);recyclerView.setBackground(bg);
这也将用于清除删除操作.
Currently, I'm implementing drag-n-move feature according to https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd and code example from https://github.com/iPaulPro/Android-ItemTouchHelper-Demo/
Here's the outcome
I would like to have background of RecycleView
to be visible, when the item is being moved.
Here's changes I had did
Set
RecycleView
background color to red -recyclerView.setBackgroundColor(Color.RED);
Provide a solid white color, on the item.
<TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="@dimen/activity_horizontal_margin" android:textAppearance="?android:attr/textAppearanceMedium" /> <ImageView android:id="@+id/handle" android:layout_width="?listPreferredItemHeight" android:layout_height="match_parent" android:layout_gravity="center_vertical|right" android:scaleType="center" android:src="@drawable/ic_reorder_grey_500_24dp" />
Here's my desired outcome.
However, there's 1 shortcoming. When, there's only a few items in RecyclerView
. Those empty area will also be filled with background color. Please see the below screenshot. The below RecyclerView
only contain 3 items.
I had try to make RecyclerView
's height wrap_content
recyclerView.setLayoutParams(
new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT
)
);
However, it makes no difference.
If the RecyclerView
is longer than the area allocated to it on the screen then there is no issue: Just set the background color of the RecyclerView
to red. However, if the items in the RecyclerView
do not fill up the space allocated to the RecyclerView
in the layout then you will see the red background in the empty space. This is what you want to eliminate.
To do this, set a OnGlobalLayoutListener
on the RecyclerView
and check if there is excess space or not. If there is not excess space, then just set the background color to red; otherwise, create a BitmapDrawable
filled with red and properly sized to provide a background to just the items on the screen and not large enough to spill into the excess area.
Here is the code that accomplishes this in RecyclerListFragment
of the project you mention.
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final RecyclerView recyclerView = new RecyclerView(container.getContext());
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
if (recyclerView.getChildCount() == 0) {
return;
}
int lastChildBottom = recyclerView.getChildAt(recyclerView.getChildCount() - 1).getBottom();
if (lastChildBottom >= recyclerView.getHeight()) {
recyclerView.setBackgroundColor(Color.RED);
return;
}
Bitmap bitmap = Bitmap.createBitmap(recyclerView.getWidth(), lastChildBottom, Bitmap.Config.ARGB_8888);
bitmap.eraseColor(Color.RED);
BitmapDrawable d = new BitmapDrawable(getResources(), bitmap);
d.setGravity(Gravity.TOP);
recyclerView.setBackground(d);
recyclerView.invalidate();
}
});
return recyclerView;
}
Here is a video of the effect:
If you have a swipe-to-remove gesture implemented, you will also have to invoke the listener when an item is removed. I also had to set the background color to a non-zero value in onItemClear()
of RecyclerListAdapter
.
An easier way is to define a drawable that can be set as a background to a RecyclerView
that draws only behind the item views.
public class RecyclerViewBackground extends Drawable {
private RecyclerView mRecyclerView;
private Bitmap mBitmap;
private Paint mPaint;
RecyclerViewBackground() {
super();
mPaint = new Paint();
mPaint.setColor(Color.RED);
}
@Override
public void draw(Canvas canvas) {
if (mRecyclerView.getChildCount() == 0) {
return;
}
int bottom = mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1).getBottom();
if (bottom >= mRecyclerView.getHeight()) {
bottom = mRecyclerView.getHeight();
}
canvas.drawRect(0, 0, canvas.getWidth(), bottom, mPaint);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}
public void attachRecyclerView(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
}
}
Attach this Drawable
to the RecyclerView
as follows:
RecyclerViewBackground bg = new RecyclerViewBackground();
bg.attachRecyclerView(recyclerView);
recyclerView.setBackground(bg);
This will also take care of swipe to delete.
这篇关于拖动n移动-即使在RecyclerView中只有少数项目,如何避免RecyclerView背景填满整个屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!