package com.wasu.cs.widget; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Message; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.util.SparseArray; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import cn.com.wasu.main.R; /** * 定制recycleview * Created by chenming on 2016/8/4. */ public class TabFocusRecycleView extends RecyclerView { // self private TabFocusRecycleView mRecycleView; // context private Context mContext; // 布局管理器 private RecyclerView.LayoutManager mLayoutManager; // 数据集合 private SparseArray spname; // 当前的位置 private int mViewPos = 0; // 获得焦点时设定item android.os.Handler handler = new android.os.Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0) { setItemFocus(); } } }; // Adapter全局 private MainAdapte mainAdapte; // 点击事件 private OnItemClickListener itemClickListener; // 焦点变换事件 private OnItemFocusChangeListener onItemFocusChangeListener; // item存在的布局文件 private int mItemLayout; // 三个drawable三种样式 private Drawable tabdefault, tabfocused, tabindicator; // leaveTag 失去焦点 private View leftFocusView; private boolean mLeaveTag = false; private static final int color_graytext = (int) R.color.netease_graytext; private static final int color_whitetext = (int) R.color.white; public TabFocusRecycleView(Context context) { super(context); mContext = context; mRecycleView = TabFocusRecycleView.this; init(); } public TabFocusRecycleView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); mContext = context; mRecycleView = TabFocusRecycleView.this; init(); } public TabFocusRecycleView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mContext = context; mRecycleView = TabFocusRecycleView.this; init(); } private void init() { mLayoutManager = new LinearLayoutManager(mContext); // 设定布局管理器 mRecycleView.setLayoutManager(mLayoutManager); // 设置适配器 mainAdapte = new MainAdapte(); mRecycleView.setAdapter(mainAdapte); // 设置分割线 mRecycleView.addItemDecoration(new DividerItemDecorations(mContext, LinearLayoutManager.VERTICAL)); // 要求RecycleView先于子控件获得焦点 mRecycleView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); mRecycleView.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean hasFocus) { if (hasFocus) { setItemFocus(); } } }); spname=new SparseArray<>();//初始化数据集合 } public void addItemData(String tabname,int pos){ spname.put(pos,tabname); mainAdapte.notifyItemChanged(pos); } public void setData( SparseArray spname){ if (spname!=null){ this.spname = spname; mainAdapte.notifyDataSetChanged(); } } public int getViewPos() { return mViewPos; } public void setViewPos(int viewPos) { mViewPos = viewPos; setHasFocus(); } /** * 设置布局和变化的三个文件 * drawSelct0 -> item的默认样式 * drawSelct1 -> item被选中时带红框的样式 * drawSelct2 -> item选中后失去焦点的样式 */ public void setLayoutAndDrawable(int itemLayout, Drawable drawSelct0, Drawable drawSelct1, Drawable drawSelct2) { mItemLayout = itemLayout; tabdefault = drawSelct0; tabfocused = drawSelct1; tabindicator = drawSelct2; } /** * 每两个字符之间增加换行符 * author chenming */ @NonNull private String setNewLine(String input) { StringBuilder stringBuilder = new StringBuilder(input); stringBuilder.insert(2, "\n"); return stringBuilder.toString(); } /** * tab栏左侧获取焦点的视图 * * @param leftFocusView */ public void setLeftFocusView(View leftFocusView) { this.leftFocusView = leftFocusView; } /** * Recycleview之间focus失效,使用外部调用来识别失去焦点 */ public void setLeaveTag() { mLeaveTag = true; } private class MainAdapte extends RecyclerView.Adapter { private int tabsCount = 0; @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(mItemLayout, parent, false)); return holder; } @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { tabsCount = getItemCount(); if (null!=spname.get(position)){ holder.textview.setText(setNewLine(spname.get(position))); } // 焦点变换监听 View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean hasFoucs) { // if (mLeaveTag && mViewPos != 0){ if (mLeaveTag) { mLeaveTag = false; setItemFocus(); return; } mLeaveTag = false; if (hasFoucs) { setDefult(); // 刷新位置 mViewPos = holder.getLayoutPosition(); setHasFocus(); } else { mViewPos = holder.getLayoutPosition(); setLeaveFocus(); } } }; holder.itemView.setOnFocusChangeListener(onFocusChangeListener); // 添加点击事件 if (itemClickListener != null) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { itemClickListener.onItemClick(position, spname.get(position)); } }); } //对触屏设备添加触摸事件监听 holder.itemView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { return v.requestFocus(); } return false; } }); //对按键焦点进行控制 holder.itemView.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT && event.getAction() == KeyEvent.ACTION_DOWN) { leftFocusView.requestFocus(); return true; } else if (position == tabsCount - 1 && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && event.getAction() == KeyEvent.ACTION_DOWN) { mRecycleView.getItemView(0).requestFocus(); mViewPos = 0; return true; } else if (position == 0 && keyCode == KeyEvent.KEYCODE_DPAD_UP && event.getAction() == KeyEvent.ACTION_DOWN) { mRecycleView.getItemView(tabsCount-1).requestFocus(); mViewPos=tabsCount-1; return true; } return false; } }); } @Override public int getItemCount() { return spname != null ? spname.size() : 0; } class MyViewHolder extends RecyclerView.ViewHolder { TextView textview; public MyViewHolder(View itemView) { super(itemView); itemView.setFocusable(true); textview = (TextView) itemView.findViewById(R.id.neteasenews_tab_name); } } } /** * 获取指定位置的itemview */ private View getItemView(int index) { return mLayoutManager.findViewByPosition(index); } /*** * 设置焦点到position制定的位置 **/ private void setItemFocus() { View view = getItemView(mViewPos); if (view == null) { handler.sendEmptyMessageDelayed(0, 100); } else { setHasFocus(); view.requestFocus(); } } /** -----------------------------焦点变换处理----------------------------- **/ /** * 恢复默认显示 */ private void setDefult() { // 把上一个恢复默认 LinearLayout linearLayout = (LinearLayout) getItemView(mViewPos); if (linearLayout != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { linearLayout.setBackground(tabdefault); } // 恢复字体颜色 TextView textView = (TextView) linearLayout.getChildAt(0); if (textView != null) { textView.setTextColor(getResources().getColor(R.color.netease_graytext)); } } } /** * 设置focused状态 */ private void setHasFocus() { // 加红色边框 LinearLayout linearLayout1 = (LinearLayout) getItemView(mViewPos); if (linearLayout1 != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { linearLayout1.setBackground(tabfocused); } // 设置字体颜色 TextView textView1 = (TextView) linearLayout1.getChildAt(0); if (textView1 != null) { textView1.setTextColor(getResources().getColor(R.color.white)); } } // 焦点变换回调 onItemFocusChangeListener.onFocusChange(mViewPos); } /** * 设置indicator状态 **/ private void setLeaveFocus() { LinearLayout linearLayout = (LinearLayout) getItemView(mViewPos); if (linearLayout != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { linearLayout.setBackground(tabindicator); } // 设置字体颜色 TextView textView = (TextView) linearLayout.getChildAt(0); if (textView != null) { textView.setTextColor(getResources().getColor(R.color.white)); } } } /** -----------------------------事件接口---------------------------------- **/ /** * item 点击事件接口 * @param */ public interface OnItemClickListener { void onItemClick(int position, T data); } /** * 设置点击事件 */ public void setOnItemClickListener(OnItemClickListener li) { itemClickListener = li; } /** * item 焦点变换 */ public interface OnItemFocusChangeListener { void onFocusChange(int position); } public void setOnItemFocusChangeListener(OnItemFocusChangeListener li) { onItemFocusChangeListener = li; } }