[英]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.