ViewGroup getChildDrawingOrder与焦点Focus放大遮挡

来源:互联网 发布:软件行业的发展趋势 编辑:程序博客网 时间:2024/06/06 13:02

做AndroidTV项目时,通常都会要实现如下图的功能,某个控件获取焦点后放大,并且显示在最上层。
可以通过getChildDrawingOrder方法实现。

这里写图片描述

代码如下
RecyclerView

package com.test.wanglu.ordertest;import android.content.Context;import android.graphics.Canvas;import android.support.annotation.Nullable;import android.support.v7.widget.RecyclerView;import android.util.AttributeSet;public class ScaleRecyclerView extends RecyclerView{    private int mSelectedPosition=0;    public ScaleRecyclerView(Context context) {        super(context);        init();    }    public ScaleRecyclerView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        init();    }    public ScaleRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init();    }    private void init() {        //启用子视图排序功能        setChildrenDrawingOrderEnabled(true);    }    @Override    public void onDraw(Canvas c) {        mSelectedPosition = getChildAdapterPosition(getFocusedChild());        super.onDraw(c);    }    @Override    protected int getChildDrawingOrder(int childCount, int i) {        int position = mSelectedPosition;        if (position < 0) {            return i;        } else {            if (i == childCount - 1) {                if (position > i) {                    position = i;                }                return position;            }            if (i == position) {                return childCount - 1;            }        }        return i;    }}

Activity

package com.test.wanglu.ordertest;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import java.util.List;/** * Created by l.wang(516066490@qq.com) on 2017/8/25. */public class MainActivity extends AppCompatActivity{    private ScaleRecyclerView rv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        rv = findViewById(R.id.rv);        rv.setLayoutManager(new GridLayoutManager(this,3, LinearLayoutManager.VERTICAL,false));        rv.setAdapter(new CommonRVAdapter<String>()        {            @Override            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {                View v = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_subnav, parent, false);                return new RecyclerView.ViewHolder(v)                {                };            }            @Override            public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {                    ImageView iv =holder.itemView.findViewById(R.id.iv);                    iv.setOnFocusChangeListener(new View.OnFocusChangeListener()                    {                        @Override                        public void onFocusChange(View view, boolean b) {                            rv.invalidate();//这句不能少                            if(b){                                view.animate().scaleX(1.2f).scaleY(1.2f).setDuration(300).start();                            }else {                                view.animate().scaleX(1).scaleY(1).setDuration(300).start();                            }                        }                    });            }            @Override            public int getItemCount() {                return 10;            }        });    }    public  abstract class CommonRVAdapter<T> extends RecyclerView.Adapter    {        private List<T> data;        public CommonRVAdapter() {        }        public CommonRVAdapter(List<T> data) {            this.data = data;        }        @Override        public int getItemCount() {            return data == null ? 0 : data.size();        }        public List<T> getData() {            return data;        }        public void setData(List<T> data) {            this.data = data;        }    }}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout    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"    android:orientation="vertical"    tools:context="com.test.wanglu.ordertest.MainActivity">    <com.test.wanglu.ordertest.ScaleRecyclerView        android:id="@+id/rv"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:clipChildren="false"        android:clipToPadding="false"        android:descendantFocusability="afterDescendants"        /></LinearLayout>

android:descendantFocusability=”afterDescendants”不能少,childView优先获取焦点

item_subnav.xml

<?xml version="1.0" encoding="utf-8"?><ImageView    android:id="@+id/iv"    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:adjustViewBounds="true"    android:focusable="true"    android:focusableInTouchMode="true"    android:clickable="true"    android:src="@drawable/menu_date"/>

因为imageview默认不能获取焦点,我用的手机测试的,所以加上
android:focusable=”true”
android:focusableInTouchMode=”true”
这2句,
android:clickable=”true”也不能少,不然手机测试时,点击无法获取焦点

原创粉丝点击