簡體   English   中英

模糊擴展的 RecyclerView 項目的周圍(模糊 RecyclerView 除了其項目之一)

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

(將模糊的視圖放在項目內容的后面,然后在RecyclerViewViewHolder處理模糊可見性,就像我在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM