溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android如何自定義ViewGroup實現(xiàn)朋友圈九宮格控件

發(fā)布時間:2021-07-13 14:55:48 來源:億速云 閱讀:213 作者:chen 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Android如何自定義ViewGroup實現(xiàn)朋友圈九宮格控件”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

目錄
  • 一、簡介

    • 1.1、效果圖如下

    • 1.2、主要功能如下

  • 二、使用

    • 2.1、自定義屬性如下

    • 2.2、布局中使用自定義NineImageLayout

    • 2.3、Adapter方式綁定數(shù)據(jù)和UI

    • 2.4、列表里面使用

  • 三、源碼地址

    一、簡介

    最近項目里有個類似微信朋友圈的九圖控件的需求,Github找了一下,發(fā)現(xiàn)都不太滿足需求,我需要單張圖片的時候可以按照圖片寬高比列在一定范圍內(nèi)自適應,而大多開源項目單張圖片也是一個小正方形,所以,干脆自己動手寫一個

    1.1、效果圖如下

    Android如何自定義ViewGroup實現(xiàn)朋友圈九宮格控件

    1.2、主要功能如下

    1:單張圖片的時候支持按照圖片寬高比列在設定區(qū)域內(nèi)自適應

    2:Adapter方式綁定數(shù)據(jù)和UI

    3:圖片點擊事件回調(diào)

    4:設置圖片間隔大小

    5:自由通過Glide設置ImageView圓角效果

    二、使用

    2.1、自定義屬性如下

    <resources>
        <declare-styleable name="NineImageLayout">
            <!-- 控件寬高 -->
            <attr name="nine_layoutWidth" format="dimension"/>
            <!-- 單張圖片時的最大寬高范圍-->
            <attr name="nine_singleImageWidth" format="dimension" />
            <!-- 圖片之間間隙大小 -->
            <attr name="nine_imageGap" format="dimension" />
        </declare-styleable>
    </resources>

    2.2、布局中使用自定義NineImageLayout

     <com.cyq.customview.nineLayout.view.NineImageLayout
            android:id="@+id/nine_image_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tv_title"
            android:layout_marginTop="20dp"
            app:nine_imageGap="4dp"
            app:nine_layoutWidth="300dp"
            app:nine_singleImageWidth="180dp" />

    2.3、Adapter方式綁定數(shù)據(jù)和UI

    其中Glide.asBitmap是為了計算圖片寬高,如果后臺有返回圖片的寬高可以省略這一步,直接setSingleImage(width, height,imageView),

    Ps:如果可以建議后臺返回圖片寬高,這樣可以避免單張圖片的時候控件高度跳屏,比如我限制單張圖片寬高在200dp范圍,要展示寬1000px高500px的時候,在圖片未加載完成時控件寬高為200dp,圖片加載完成后高度變?yōu)?00dp,會有一個不好的用戶體驗,所以建議上傳圖片的時候記錄圖片寬高信息

    nineImageLayout.setAdapter(new NineImageAdapter() {
                @Override
                protected int getItemCount() {
                    return mData.size();
                }
    
                @Override
                protected View createView(LayoutInflater inflater, ViewGroup parent, int i) {
                    return inflater.inflate(R.layout.item_img_layout, parent, false);
                }
    
                @Override
                protected void bindView(View view, final int i) {
                    final ImageView imageView = view.findViewById(R.id.iv_img);
                    Glide.with(mContext).load(mData.get(i)).into(imageView);
                    if (mData.size() == 1) {
                        Glide.with(mContext)
                                .asBitmap()
                                .load(mData.get(0))
                                .into(new SimpleTarget<Bitmap>() {
                                    @Override
                                    public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition) {
                                        final int width = bitmap.getWidth();
                                        final int height = bitmap.getHeight();
                                        nineImageLayout.setSingleImage(width, height,imageView);
                                    }
                                });
                        Glide.with(mContext).load(mData.get(0)).into(imageView);
                    } else {
                        Glide.with(mContext).load(mData.get(i)).into(imageView);
                    }
                }
    
                @Override
                public void OnItemClick(int i, View view) {
                    super.OnItemClick(position, view);
                    Toast.makeText(mContext, "position:" + mData.get(i), Toast.LENGTH_SHORT).show();
                }
            });

    2.4、列表里面使用

    頁面放一個RecyclerView

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".nineLayout.NineImageLayoutActivity">
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </FrameLayout>

    item布局如下

    <?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"
        android:layout_margin="20dp">
    
        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="標題"
            android:textColor="@android:color/black"
            android:textSize="18sp" />
    
        <com.cyq.customview.nineLayout.view.NineImageLayout
            android:id="@+id/nine_image_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tv_title"
            android:layout_marginTop="20dp"
            app:nine_imageGap="4dp"
            app:nine_layoutWidth="300dp"
            app:nine_singleImageWidth="180dp" />
    </RelativeLayout>

    Activity中構(gòu)造一下測試數(shù)據(jù),大致代碼如下

    public class NineImageLayoutActivity extends AppCompatActivity {
        private RecyclerView mRecyclerView;
        private MyAdapter mAdapter;
        private Random random;
        private final String URL_IMG = "http://q3x62hkt1.bkt.clouddn.com/banner/58f57dfa5bb73.jpg";
        private final String URL_IMG_2 = "http://q3x62hkt1.bkt.clouddn.com/timg.jpeg";
        private List<List<String>> mList = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_nine_image_layout);
            random = new Random();
            List<String> testList = new ArrayList<>();
            testList.add(URL_IMG_2);
            for (int i = 0; i < 100; i++) {
                int count = i % 9 + 1;
                List<String> list = new ArrayList<>();
                for (int j = 0; j < count; j++) {
                    list.add(URL_IMG);
                }
                if (i % 8 == 0) {
                    mList.add(testList);
                }
                mList.add(list);
            }
            mRecyclerView = findViewById(R.id.recyclerview);
            mAdapter = new MyAdapter(mList, this);
            mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
            mRecyclerView.setAdapter(mAdapter);
        }
    }

    MyAdapter中設置數(shù)據(jù)

    import java.util.List;
    
    /**
     * @author : ChenYangQi
     * date   : 2020/1/16 13:49
     * desc   :
     */
    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
        private List<List<String>> mList;
        private Context mContext;
    
        public MyAdapter(List<List<String>> mList, Context mContext) {
            this.mList = mList;
            this.mContext = mContext;
        }
    
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(mContext).inflate(R.layout.item_nine_img_layout_list, parent, false);
            return new MyViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
            final List<String> mData = mList.get(position);
            holder.tvTitle.setText("這是" + mData.size() + "張圖片的標題");
            final NineImageLayout nineImageLayout = holder.nineImageLayout;
            holder.nineImageLayout.setAdapter(new NineImageAdapter() {
                @Override
                protected int getItemCount() {
                    return mData.size();
                }
    
                @Override
                protected View createView(LayoutInflater inflater, ViewGroup parent, int i) {
                    return inflater.inflate(R.layout.item_img_layout, parent, false);
                }
    
                @Override
                protected void bindView(View view, final int i) {
                    final ImageView imageView = view.findViewById(R.id.iv_img);
                    Glide.with(mContext).load(mData.get(i)).into(imageView);
                    if (mData.size() == 1) {
                        Glide.with(mContext)
                                .asBitmap()
                                .load(mData.get(0))
                                .into(new SimpleTarget<Bitmap>() {
                                    @Override
                                    public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition) {
                                        final int width = bitmap.getWidth();
                                        final int height = bitmap.getHeight();
                                        nineImageLayout.setSingleImage(width, height,imageView);
                                    }
                                });
                        Glide.with(mContext).load(mData.get(0)).into(imageView);
                    } else {
                        Glide.with(mContext).load(mData.get(i)).into(imageView);
                    }
                }
    
                @Override
                public void OnItemClick(int i, View view) {
                    super.OnItemClick(position, view);
                    Toast.makeText(mContext, "position:" + mData.get(i), Toast.LENGTH_SHORT).show();
                }
            });
        }
    
        @Override
        public int getItemCount() {
            return mList.size();
        }
     
        class MyViewHolder extends RecyclerView.ViewHolder {
            TextView tvTitle;
            NineImageLayout nineImageLayout;
    
            public MyViewHolder(@NonNull View itemView) {
                super(itemView);
                tvTitle = itemView.findViewById(R.id.tv_title);
                nineImageLayout = itemView.findViewById(R.id.nine_image_layout);
            }
        }
    }

    三、源碼地址

    具體自定義NineImageLayout過程,可以查看NineImageLayout

    “Android如何自定義ViewGroup實現(xiàn)朋友圈九宮格控件”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI