我有一个包含其子项的RecyclerView
:
如图所示,每个项目都可以展开(例如图中的项目 i)。
在我的项目中我使用 this blur library模糊事物,例如,单击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>
(将模糊 View 放在项目内容后面,然后在 RecyclerView
的 ViewHolder
中处理模糊可见性,就像我在每次展开/收缩项目时在对话框示例中所做的那样,但即使我在不处理它的情况下使其可见,模糊也不会显示。我尝试按计划以编程方式处理它,但模糊仍然没有显示。
所以问题是:具体就我而言 - 问题出在哪里?为什么模糊不显示?
一般来说...我怎样才能模糊RecyclerView
的展开/聚焦项目的周围(使用RealtimeBlurView
库或任何其他适合此问题解决方案的库),或者换句话说,如何模糊整个Recyclerview
除了其中一个项目/如何模糊特定View
的背景(模糊除此View
之外的所有内容。
非常感谢您的帮助! (:
最佳答案
您必须将 RealtimeBlurView
放在另一个 View 上方才能使该 View 模糊,但在您的实现中,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>
更新
由于您需要模糊除扩展项目之外的其他项目,因此您应该在适配器实现中处理它。下面的代码 fragment 展示了如何实现它。
MyAdapter.kt
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)为了处理模糊 View Z 位置,它适用于 API 21 及更高版本。为了支持较低的 API 版本,您应该在布局文件中的 FrameLayout (cardHolder)
View 之前添加另一个 Blur View ,而不是使用 View.setZ(float)
方法,使正确的 Blur View 可见。
2.当某个项目展开且其他项目模糊时,RecyclerView 的滚动仍然有效,但不会影响我的答案的功能。如果需要禁用它,您应该在 Adapter 中定义一个回调,并在 override fun onClick(v: View?)
方法中调用它,以通知 Activity 或 Fragment 禁用/启用 RecyclerView 滚动。
关于java - 模糊展开的 RecyclerView 项目的周围(模糊 RecyclerView 除了其中一项),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59969187/