[英]Blur Surrounding Of Expanded RecyclerView Item (Blur RecyclerView Except Of One Of Its Items)
我有一个RecyclerView
包含它的孩子:
正如您在图片中看到的,每个项目都可以展开(例如图片中的项目 i)。 在我的项目中,我使用这个模糊库来模糊事物,例如,单击FloatingActionButton
将其展开为一个对话框,并且对话框的周围是模糊的,如下所示:
我希望扩展的RecyclerView
项目也将其周围模糊。 我试过这个:
( 项目Item.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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.github.mmin18.widget.RealtimeBlurView
android:id="@+id/blur_view_per_active_goal_card"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
app:realtimeBlurRadius="20dp"
app:realtimeOverlayColor="#8000"
android:visibility="visible"/>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="15dp"
app:cardElevation="10dp">
<RelativeLayout
android:id="@+id/root_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/active_goal_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:orientation="horizontal"
android:padding="10dp"
android:weightSum="10">
<com.example.performancemeasurement.customViews.CustomProgressBar.CustomProgressBar
android:id="@+id/active_goal_item_progress_bar"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="9"
android:transitionName="progressBar"
android:visibility="visible"
app:enable_gradient="true" />
<ImageButton
android:id="@+id/active_goal_item_open_close_image_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/down_vector" />
</LinearLayout>
<RelativeLayout
android:id="@+id/expanded_active_goal_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:visibility="gone">
<TextView
android:id="@+id/expanded_active_goal_card_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_centerHorizontal="true"
android:text="Goal Name"
android:textColor="@android:color/black"
android:textSize="40sp"
android:textStyle="bold" />
<com.example.performancemeasurement.customViews.CustomProgressBar.CustomProgressBar
android:id="@+id/expanded_active_goal_card_progress_bar"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_below="@id/expanded_active_goal_card_label"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_centerHorizontal="true"
android:transitionName="progressBar"
app:enable_gradient="true" />
<TextView
android:id="@+id/expanded_active_goal_card_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/expanded_active_goal_card_progress_bar"
android:layout_centerHorizontal="true"
android:layout_margin="10dp"
android:maxLines="3"
android:text="Goal's Description"
android:textColor="#6F6F6F"
android:textSize="20sp"
android:textStyle="normal" />
<LinearLayout
android:id="@+id/expanded_active_goal_card_sub_goals_label_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/expanded_active_goal_card_description"
android:layout_centerHorizontal="true"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:weightSum="14">
<View
android:id="@+id/expanded_active_goal_card_sub_goal_label_left"
android:layout_width="0dp"
android:layout_height="3dp"
android:layout_weight="4"
android:background="@color/light_gray" />
<TextView
android:id="@+id/expanded_active_goal_card_sub_goals_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="6"
android:gravity="center"
android:text="SubGoals"
android:textColor="#5A5A5A"
android:textSize="25sp"
android:textStyle="bold" />
<View
android:id="@+id/expanded_active_goal_card_sub_goal_label_right"
android:layout_width="0dp"
android:layout_height="3dp"
android:layout_weight="4"
android:background="@color/light_gray" />
</LinearLayout>
<RelativeLayout
android:id="@+id/expanded_active_goal_card_sub_goals_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/expanded_active_goal_card_sub_goals_label_container"
android:layout_centerHorizontal="true"
android:layout_margin="10dp"
android:animateLayoutChanges="true"
android:elevation="15dp"
android:gravity="center">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/expanded_active_goal_card_sub_goals_recycler_view"
android:layout_width="match_parent"
android:layout_height="100dp" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
(将模糊的视图放在项目内容的后面,然后在RecyclerView
的ViewHolder
处理模糊可见性,就像我在 Dialog 示例中每次项目展开/收缩时所做的那样,但即使我在不处理它的情况下使其可见,模糊不会显示。我尝试按计划以编程方式处理它,但仍然没有出现模糊。
所以问题是:特别是在我的情况下 - 问题在哪里? 为什么不显示模糊? 一般来说......我如何模糊RecyclerView
的扩展/聚焦项目的周围(使用RealtimeBlurView
库或任何其他适合解决此问题的库),或者换句话说,我如何模糊整个Recyclerview
除了其中一项/如何模糊特定View
的背景(模糊除此View
之外的所有内容。
帮助将不胜感激! (:
您必须将RealtimeBlurView
放在另一个视图上方以使该视图模糊,但在您的实现中, RealtimeBlurView
位于CardView
下方,因此您看不到 Bure 效果。 您必须将它放在布局文件中的CardView
之后。 试试下面的代码:
<RelativeLayout 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">
<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="15dp"
app:cardElevation="10dp">
<RelativeLayout
android:id="@+id/root_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/active_goal_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:orientation="horizontal"
android:padding="10dp"
android:weightSum="10">
<com.example.performancemeasurement.customViews.CustomProgressBar.CustomProgressBar
android:id="@+id/active_goal_item_progress_bar"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="9"
android:transitionName="progressBar"
android:visibility="visible"
app:enable_gradient="true" />
<ImageButton
android:id="@+id/active_goal_item_open_close_image_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:scaleType="fitCenter"
android:src="@drawable/down_vector" />
</LinearLayout>
<RelativeLayout
android:id="@+id/expanded_active_goal_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:visibility="gone">
<TextView
android:id="@+id/expanded_active_goal_card_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_centerHorizontal="true"
android:text="Goal Name"
android:textColor="@android:color/black"
android:textSize="40sp"
android:textStyle="bold" />
<com.example.performancemeasurement.customViews.CustomProgressBar.CustomProgressBar
android:id="@+id/expanded_active_goal_card_progress_bar"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_below="@id/expanded_active_goal_card_label"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_centerHorizontal="true"
android:transitionName="progressBar"
app:enable_gradient="true" />
<TextView
android:id="@+id/expanded_active_goal_card_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/expanded_active_goal_card_progress_bar"
android:layout_centerHorizontal="true"
android:layout_margin="10dp"
android:maxLines="3"
android:text="Goal's Description"
android:textColor="#6F6F6F"
android:textSize="20sp"
android:textStyle="normal" />
<LinearLayout
android:id="@+id/expanded_active_goal_card_sub_goals_label_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/expanded_active_goal_card_description"
android:layout_centerHorizontal="true"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:weightSum="14">
<View
android:id="@+id/expanded_active_goal_card_sub_goal_label_left"
android:layout_width="0dp"
android:layout_height="3dp"
android:layout_weight="4"
android:background="@color/light_gray" />
<TextView
android:id="@+id/expanded_active_goal_card_sub_goals_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="6"
android:gravity="center"
android:text="SubGoals"
android:textColor="#5A5A5A"
android:textSize="25sp"
android:textStyle="bold" />
<View
android:id="@+id/expanded_active_goal_card_sub_goal_label_right"
android:layout_width="0dp"
android:layout_height="3dp"
android:layout_weight="4"
android:background="@color/light_gray" />
</LinearLayout>
<RelativeLayout
android:id="@+id/expanded_active_goal_card_sub_goals_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/expanded_active_goal_card_sub_goals_label_container"
android:layout_centerHorizontal="true"
android:layout_margin="10dp"
android:animateLayoutChanges="true"
android:elevation="15dp"
android:gravity="center">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/expanded_active_goal_card_sub_goals_recycler_view"
android:layout_width="match_parent"
android:layout_height="100dp" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView>
<com.github.mmin18.widget.RealtimeBlurView
android:id="@+id/blur_view_per_active_goal_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/cardView"
android:layout_alignBottom="@id/cardView"
android:layout_alignLeft="@id/cardView"
android:layout_alignRight="@id/cardView"
app:realtimeBlurRadius="20dp"
app:realtimeOverlayColor="#8000"
android:visibility="visible"/>
</RelativeLayout>
更新
由于您需要模糊除扩展项之外的其他项,您应该在您的适配器实现中处理它。 下面的代码片段展示了如何实现它。
我的适配器文件
class MyAdapter : RecyclerView.Adapter<MyAdapter.MyViewHolder>(), View.OnClickListener {
val items = ArrayList<Item>()
var expandedItemIndex = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter.MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_row, parent, false)
return MyViewHolder(view, this)
}
override fun getItemCount() = items.size
override fun onBindViewHolder(holder: MyAdapter.MyViewHolder, position: Int) {
items.get(position)?.apply { holder.bind(this, expandedItemIndex) }
}
override fun onClick(v: View?) {
v?.let {
if(it.id == R.id.blur) {
expandedItemIndex = -1
notifyDataSetChanged()
} else if(it.id == R.id.expand_btn) {
val holder = it.getTag() as MyViewHolder
if (expandedItemIndex == holder.adapterPosition) {
expandedItemIndex = -1;
notifyDataSetChanged()
} else {
expandedItemIndex = holder.adapterPosition
notifyDataSetChanged()
}
}
}
}
class MyViewHolder(itemView: View, onClickListener: View.OnClickListener) : RecyclerView.ViewHolder(itemView) {
val textView : TextView = itemView.findViewById(R.id.text)
val expandButton : ImageView = itemView.findViewById(R.id.expand_btn)
val expandArea : View = itemView.findViewById(R.id.expanded_area);
val blur : View = itemView.findViewById(R.id.blur);
init {
expandButton.setOnClickListener(onClickListener)
blur.setOnClickListener(onClickListener)
}
fun bind(item: Item, expandedItemIndex: Int) {
textView.text = item.value.toString()
expandButton.setTag(this)
if(expandedItemIndex >= 0) {
blur.visibility = View.VISIBLE
if(expandedItemIndex == adapterPosition) {
blur.z = -1f
expandArea.visibility = View.VISIBLE
expandButton.setImageResource(android.R.drawable.arrow_up_float)
} else {
blur.z = 0f
expandArea.visibility = View.GONE
expandButton.setImageResource(android.R.drawable.arrow_down_float)
}
} else {
expandArea.visibility = View.GONE
blur.visibility = View.INVISIBLE
}
}
}
}
layout_row.xml
<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="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="@+id/cardHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="15dp"
app:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Header Text" />
<ImageView
android:id="@+id/expand_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@android:drawable/arrow_down_float" />
</LinearLayout>
<LinearLayout
android:id="@+id/expanded_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Expanded Line 1"></TextView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Expanded Line 2"></TextView>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>
<com.github.mmin18.widget.RealtimeBlurView
android:id="@+id/blur"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/cardHolder"
android:layout_alignBottom="@id/cardHolder"
app:realtimeBlurRadius="20dp"
app:realtimeOverlayColor="#8000" />
</RelativeLayout>
MyAdapterJava.Java (适配器的Java实现)
public class MyAdapterJava extends RecyclerView.Adapter<MyAdapterJava.MyViewHolder> implements View.OnClickListener{
List<Item> items = new ArrayList<Item>();
int expandedItemIndex = -1;
@NonNull
@Override
public MyAdapterJava.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_row, parent, false);
return new MyViewHolder(view, this);
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public void onBindViewHolder(@NonNull MyAdapterJava.MyViewHolder holder, int position) {
holder.bind(items.get(position), expandedItemIndex);
}
@Override
public void onClick(View v) {
if(v != null) {
if(v.getId() == R.id.blur) {
expandedItemIndex = -1;
notifyDataSetChanged();
} else if(v.getId() == R.id.expand_btn) {
MyViewHolder holder = (MyViewHolder) v.getTag();
if (expandedItemIndex == holder.getAdapterPosition()) {
expandedItemIndex = -1;
notifyDataSetChanged();
} else {
expandedItemIndex = holder.getAdapterPosition();
notifyDataSetChanged();
}
}
}
}
static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;
ImageView expandButton;
View expandArea;
View blur;
public MyViewHolder(View itemView, View.OnClickListener onClickListener) {
super(itemView);
textView = itemView.findViewById(R.id.text);
expandButton = itemView.findViewById(R.id.expand_btn);
expandArea = itemView.findViewById(R.id.expanded_area);
blur = itemView.findViewById(R.id.blur);
expandButton.setOnClickListener(onClickListener);
blur.setOnClickListener(onClickListener);
}
public void bind(Item item, int expandedItemIndex) {
textView.setText(String.valueOf(item.getValue()));
expandButton.setTag(this);
if(expandedItemIndex >= 0) {
blur.setVisibility(View.VISIBLE);
if(expandedItemIndex == getAdapterPosition()) {
blur.setZ(-1f);
expandArea.setVisibility(View.VISIBLE);
expandButton.setImageResource(android.R.drawable.arrow_up_float);
} else {
blur.setZ(0f);
expandArea.setVisibility(View.GONE);
expandButton.setImageResource(android.R.drawable.arrow_down_float);
}
} else {
expandArea.setVisibility(View.GONE);
blur.setVisibility(View.INVISIBLE);
}
}
}
}
PS:
1. 由于此代码使用View.SetZ(float)来处理模糊视图 Z 位置,因此它适用于 API 21 及更高版本。 为了支持较低的 API 版本,您应该在布局文件中的FrameLayout (cardHolder)
视图之前添加另一个模糊视图,而不是使用View.setZ(float)
方法,使正确的模糊视图可见。
2.当一个项目被展开而其他项目变得模糊时,RecyclerView 的滚动仍然有效,但它不会影响我的答案的功能。 如果您需要禁用它,您应该在您的适配器中定义一个回调并在override fun onClick(v: View?)
方法中调用它以通知活动或片段禁用/启用 RecyclerView 滚动。
您可以使用模糊库https://github.com/wasabeef/Blurry 。 这是制作模糊背景的最简单方法。
有了这个库,你只需要使用下面的片段
Blurry.with(context).radius(10).sampling(8).color(Color.argb(66, 255, 255, 0)).async().onto(rootView);
希望这将适合您的要求完美!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.