Android 사용자 정의 ViewGroup 친구 권 9 궁 격 컨트롤 실현

프로필
최근 프로젝트 에 위 챗 모멘트 와 비슷 한 9 개의 그림 컨트롤 에 대한 수요 가 있 습 니 다.Github 이 찾 아 보 니 모두 수 요 를 만족 시 키 지 못 했 습 니 다.저 는 한 장의 그림 이 필요 할 때 그림 의 너비 와 높이 에 따라 일정한 범위 에서 적응 할 수 있 습 니 다.그리고 대부분 오픈 소스 프로젝트 의 한 장의 그림 도 작은 정사각형 이기 때문에 아예 직접 작성 하 겠 습 니 다.
1.1 효과 도 는 다음 과 같다

1.2 주요 기능 은 다음 과 같다.
1:한 장의 그림 일 때 그림 의 너비 와 높이 에 따라 설정 영역 에 적응 하 는 것 을 지원 합 니 다.
2:Adapter 방식 으로 데이터 와 UI 바 인 딩
3:그림 클릭 이벤트 리 셋
4:그림 간격 설정
5:글 라 이 드 를 통 해 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 방식 으로 데이터 와 UI 를 연결 합 니 다.
그 중에서 Glide.asBitmap 은 그림 의 너비 와 높이 를 계산 하기 위해 서 입 니 다.배경 에 그림 을 되 돌려 주 는 너비 가 있 으 면 이 단 계 를 생략 하고 setSingleImage(width,height,imageView)를 직접 설정 할 수 있 습 니 다.
P:배경 에서 그림 의 너비 와 높이 를 되 돌려 주 는 것 을 권장 할 수 있다 면 한 장의 그림 을 불 러 올 때 컨트롤 의 높이 가 200 dp 범위 에 있 는 것 을 피 할 수 있 습 니 다.너비 1000 px 높이 500 px 를 보 여 주 려 면 그림 을 불 러 오지 않 았 을 때 컨트롤 의 너비 가 200 dp 이 고 그림 추가 가 완 료 된 후에 높이 가 100 dp 로 바 뀌 면 좋 지 않 은 사용자 체험 을 할 수 있 습 니 다.그래서 사진 을 올 릴 때 사진 의 너비 와 높이 정 보 를 기록 하 는 것 을 권장 합 니 다.

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>
항목 레이아웃 은 다음 과 같 습 니 다.

<?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 에서 테스트 데 이 터 를 구성 해 보 세 요.대체적으로 코드 는 다음 과 같 습 니 다.

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 에서 데이터 설정

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);
        }
    }
}

3.소스 주소
구체 적 인 사용자 정의 NineImageLayout 과정 을 볼 수 있 습 니 다NineImageLayout
총화
안 드 로 이 드 사용자 정의 뷰 그룹 이 친구 권 구 궁 격 컨트롤 을 실현 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 안 드 로 이 드 친구 권 구 궁 격 컨트롤 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부탁드립니다!

좋은 웹페이지 즐겨찾기