package com.wasu.cs.widget; import android.content.Context; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Message; import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; 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 java.util.List; import cn.com.wasu.main.R; /** * Created by chenming on 2016/11/10. * * @Description: 动画列表左侧的tab控件 * @email chenming@wasu.com */ public class CartoonRecyclerView extends RecyclerView { private CartoonRecyclerView mRecycleView; // context private Context mContext; // 布局管理器 private LinearLayoutManager mLayoutManager; // 数据集合(专用) private List mData; // 记录当前的位置(0是初始位置) private int mViewPos = 0; // 获得焦点时设定item // Adapter全局(用于刷新数据) private CartoonTabAdapter mainAdapte; // 点击事件 private CartoonRecyclerView.OnItemClickListener itemClickListener; // 焦点变换事件 private CartoonRecyclerView.OnItemFocusChangeListener onItemFocusChangeListener; // item存在的布局文件 private int mItemLayout; // 三个drawable三种样式 private Drawable tabdefault, tabfocused, tabindicator; // leaveTag 失去焦点 private View rightFocusView; private boolean mLeaveTag = false; private int tabsCount = 0; // LinearLayout mLinearLayout; TextView mTextView; public CartoonRecyclerView(Context context) { super(context); mContext = context; mRecycleView = CartoonRecyclerView.this; init(); } public CartoonRecyclerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); mContext = context; mRecycleView = CartoonRecyclerView.this; init(); } public CartoonRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mContext = context; mRecycleView = CartoonRecyclerView.this; init(); } private void init() { mLayoutManager = new LinearLayoutManager(mContext); // 设定布局管理器 mRecycleView.setLayoutManager(mLayoutManager); // 设置适配器 mainAdapte = new CartoonTabAdapter(); mRecycleView.setAdapter(mainAdapte); // 设置间隔 mRecycleView.addItemDecoration(new RecyclerView.ItemDecoration() { @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); int count = parent.getChildCount(); int spacingInPixels = getResources().getDimensionPixelOffset(R.dimen.d_20dp); int pos = parent.getChildPosition(view); if (pos == 0) { outRect.top = 0; } else if (pos == count - 1) { outRect.top = spacingInPixels; outRect.bottom = 0; } else { outRect.top = spacingInPixels; } } }); // 要求RecycleView先于子控件获得焦点 mRecycleView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); mRecycleView.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean hasFocus) { if (hasFocus) { setItemFocus(); } } }); } android.os.Handler handler = new android.os.Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0) { setItemFocus(); } } }; /** * 必须调用这个setData * SET后自动刷新 */ public void setData(List data) { if (data != null && data.size() > 0) { mData = data; } mainAdapte.notifyDataSetChanged(); } public void addItemData(String name) { mData.add(name); mainAdapte.notifyItemChanged(mData.size()); } public int getViewPos() { return mViewPos; } /** * 设置布局和变化的三个文件 *

* 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; } /** * tab栏左侧获取焦点的视图 * * @param */ public void setRightFocusView(View FocusView) { this.rightFocusView = FocusView; } @Override public LinearLayoutManager getLayoutManager() { return mLayoutManager; } /** * Recycleview之间focus失效,使用外部调用来识别失去焦点 */ public void setLeaveTag() { mLeaveTag = true; } private class CartoonTabAdapter extends RecyclerView.Adapter { @Override public CartoonTabViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { CartoonTabViewHolder holder = new CartoonTabViewHolder(LayoutInflater.from(mContext).inflate(mItemLayout, parent, false)); return holder; } @Override public void onBindViewHolder(final CartoonTabViewHolder holder, final int position) { tabsCount = getItemCount(); holder.textview.setText(mData.get(position)); // 这样设置才能使控件获得焦点 holder.itemView.setFocusable(true); // 焦点变换监听 View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean hasFoucs) { 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, mData.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 (event.getAction() == KeyEvent.ACTION_DOWN){ switch (keyCode){ case KeyEvent.KEYCODE_DPAD_RIGHT: if (rightFocusView != null) { rightFocusView.requestFocus(); return true; } break; case KeyEvent.KEYCODE_DPAD_DOWN: if (position == tabsCount - 1){ mRecycleView.getItemView(mLayoutManager.findFirstVisibleItemPosition()).requestFocus(); mViewPos = 0; return true; } break; case KeyEvent.KEYCODE_DPAD_UP: if (position == 0){ mRecycleView.getItemView(tabsCount - 1).requestFocus(); mViewPos = tabsCount - 1; return true; } break; default: break; } } return false; } }); } @Override public int getItemCount() { return mData != null ? mData.size() : 0; } class CartoonTabViewHolder extends RecyclerView.ViewHolder { TextView textview; public CartoonTabViewHolder(View itemView) { super(itemView); textview = (TextView) itemView.findViewById(R.id.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() { // 把上一个恢复默认 mLinearLayout = (LinearLayout) getItemView(mViewPos); if (mLinearLayout != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mLinearLayout.setBackground(tabdefault); } // 字体恢复蓝色 mTextView = (TextView) mLinearLayout.getChildAt(0); if (mTextView != null) { mTextView.setTextColor(getResources().getColor(R.color.btn_bule_text)); } } } /** * 设置focused状态 */ private void setHasFocus() { // change background mLinearLayout = (LinearLayout) getItemView(mViewPos); if (mLinearLayout != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mLinearLayout.setBackground(tabfocused); } // set text white mTextView = (TextView) mLinearLayout.getChildAt(0); if (mTextView != null) { mTextView.setTextColor(getResources().getColor(R.color.white)); } } // 焦点变换回调 onItemFocusChangeListener.onFocusChange(mViewPos); } /** * 设置indicator状态 **/ private void setLeaveFocus() { mLinearLayout = (LinearLayout) getItemView(mViewPos); if (mLinearLayout != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mLinearLayout.setBackground(tabindicator); } } } /** -----------------------------事件接口---------------------------------- **/ /** * item 点击事件接口 * * @param */ public interface OnItemClickListener { void onItemClick(int position, T data); } /** * 设置点击事件 */ public void setOnItemClickListener(CartoonRecyclerView.OnItemClickListener li) { itemClickListener = li; } /** * item 焦点变换 */ public interface OnItemFocusChangeListener { void onFocusChange(int position); } public void setOnItemFocusChangeListener(CartoonRecyclerView.OnItemFocusChangeListener li) { onItemFocusChangeListener = li; } }