android TV端 多个GridView焦点跳转。跳转到GridView指定位置。

       这几天做了个项目有个页面是关于节目类型的标志设置,一共有三种颜色,可以标志三种类型。每种颜色可以选择不同的类型。如果一个颜色已经选择了一种类型,其他两种颜色相应的类型就要置灰。当焦点移动到这一类型时要跳过。刚打开这个页面时,焦点要跳转到已经选择的类型上。当从上一个颜色切换到下一种颜色时,焦点也要跳转到下一个颜色选择的类型上。节目类型一共11个,三个颜色下的节目类型是一个横向的GridView,焦点切换时,外套的HorizontalScrollView也要滚动到相应位置。还要适配Rtl布局,初始效果如下图:

android TV端 多个GridView焦点跳转。跳转到GridView指定位置。_第1张图片

重点:

1. 第一种颜色已有选中类型的情况下,初始化时,焦点的跳转。

2. 在一种颜色选中一种类型时,下一种颜色该类型的置灰

3. 按左右键时,焦点的跳转及HorizontalScrollView的滚动。

4. 从上一种颜色跳转到下一种颜色时焦点的跳转

5. 当选中一个类型时,焦点跳转,position虽然跳过去了,但焦点还是会跑到这个类型上;

6. 当选中了两个相连的类型时,焦点的跳转(有可能只跳了一格),当选中了最后两个相连的类型时的特殊处理,与选中前面两个类型不同。

7. 当选中了三个相连类型时,焦点跳转(有可能只跳一格,也有可能一格也跳不过去),当选中最后三个相连的类型时的特殊处理。

8. Rtl布局时,GridView的各个项虽然已经左右翻转,但position的位置还是从左边开始的。scrollView的滚动位置需要特别注意。

9. 当每个颜色选中第一项或最后一项以及中间项时,左右箭头的显示;

上代码:

 

public class EPGTypeDialog extends Dialog {
    private static final String TAG = "EPGTypeDialog";
    public static boolean mHasEditType;
    GridView epgList,gv_red,gv_blue;
    HorizontalScrollView hsv_green,hsv_red,hsv_blue;
    EPGTypeListAdapter listAdapter,redAdapter,blueAdapter;
    List mData;
    private Context mContext;
    public static TextView tv_orange,tv_blue,tv_red;
    EPGSaveValue sv;
    List gridViewList = new ArrayList();
    private Handler myHandler = new Handler();
    int gridViewIndex = 0;//当前在哪个颜色
    int[] selectIndex = new int[3];//选中的三个类型的位置
    String[] keyStr = {"orange1","red2","blue3"};
    int itemWidth = 0;
    private ImageView iv_green_left,iv_green_right,iv_red_left,iv_red_right,iv_blue_left,iv_blue_right;

    public EPGTypeDialog(@NonNull Context context) {
        super(context);
        this.mContext = context;
        sv = EPGSaveValue.getInstance(mContext);
    }

    public EPGTypeDialog(@NonNull Context context, int themeResId) {
        super(context, themeResId);
        this.mContext = context;
        sv = EPGSaveValue.getInstance(mContext);
    }

    protected EPGTypeDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
        this.mContext = context;
        sv = EPGSaveValue.getInstance(mContext);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_epgtype_dialog);
        setWindowPosition();
        initUI();
    }

    public void initUI(){
        epgList = (GridView)findViewById(R.id.gv_green);
        gv_red = (GridView)findViewById(R.id.gv_red);
        gv_blue = (GridView)findViewById(R.id.gv_blue);

        hsv_green = (HorizontalScrollView)findViewById(R.id.hsv_green);
        hsv_red = (HorizontalScrollView)findViewById(R.id.hsv_red);
        hsv_blue = (HorizontalScrollView)findViewById(R.id.hsv_blue);

        tv_orange = (TextView)findViewById(R.id.type_green);
        tv_red = (TextView)findViewById(R.id.type_red);
        tv_blue = (TextView)findViewById(R.id.type_blue);

        iv_green_left = (ImageView)findViewById(R.id.iv_green_left);
        iv_green_right = (ImageView)findViewById(R.id.iv_green_right);
        iv_red_left = (ImageView)findViewById(R.id.iv_red_left);
        iv_red_right = (ImageView)findViewById(R.id.iv_red_right);
        iv_blue_left = (ImageView)findViewById(R.id.iv_blue_left);
        iv_blue_right = (ImageView)findViewById(R.id.iv_blue_right);

        listAdapter = new EPGTypeListAdapter(mContext,epgList);
        redAdapter = new EPGTypeListAdapter(mContext,gv_red);
        blueAdapter = new EPGTypeListAdapter(mContext,gv_red);

        mData = listAdapter.loadEPGFilterTypeData("");
        gridViewList.add(epgList);
        gridViewList.add(gv_red);
        gridViewList.add(gv_blue);
        listAdapter.setGridViewList(gridViewList);
        redAdapter.setGridViewList(gridViewList);
        blueAdapter.setGridViewList(gridViewList);
        listAdapter.setEPGData(mData);
        redAdapter.setEPGData(mData);
        blueAdapter.setEPGData(mData);
        listAdapter.setSource(1);
        redAdapter.setSource(2);
        blueAdapter.setSource(3);

        if(mData != null){
            epgList.setAdapter(listAdapter);
            gv_red.setAdapter(redAdapter);
            gv_blue.setAdapter(blueAdapter);
            tv_orange.setText(mData.get(0).getData());
            tv_red.setText(mData.get(0).getData());
            tv_blue.setText(mData.get(0).getData());
        }

        //横向gridview
        int length = 138;
        int size = 0;
        if(mData != null && mData.size() != 0){
            size = mData.size();
        }
        DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
        float density = dm.density;
        int gridviewWidth = (int)(size *(length +12)*density);
        itemWidth = (int)(length*density);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(gridviewWidth, ViewGroup.LayoutParams.FILL_PARENT);
        epgList.setLayoutParams(params);
        epgList.setColumnWidth(itemWidth);
        epgList.setNumColumns(size);

        epgList.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if(event.getAction() == KeyEvent.ACTION_DOWN){
                    if(listAdapter.ismFocus()){
                        listAdapter.onMainKey(v,keyCode);

                        int mPosition = 0;
                        if(isRtl()){
                            //rtl布局下,GridView的位置顺序相反
                            mPosition = mData.size()-1-EPGTypeListAdapter.mPosition;
                        }else{
                            mPosition = EPGTypeListAdapter.mPosition;
                        }

                        //操作外套scrollView的滑动位置和两边箭头显示与隐藏
                        switch (keyCode){
                            case KeyEvent.KEYCODE_DPAD_RIGHT:
                                int scrollWidth1 = itemWidth * mPosition;
                                //smoothScrollTo指滑动到的位置,smoothScrollBy指滑动的距离
                                hsv_green.smoothScrollTo(scrollWidth1,0);

                                if(EPGTypeListAdapter.mPosition == mData.size()-1){//ltr
                                    iv_green_right.setVisibility(View.INVISIBLE);
                                }else if(EPGTypeListAdapter.mPosition == 0){//rtl
                                    iv_green_left.setVisibility(View.INVISIBLE);
                                }else{
                                    iv_green_left.setVisibility(View.VISIBLE);
                                    iv_green_right.setVisibility(View.VISIBLE);
                                }
                                break;
                            case KeyEvent.KEYCODE_DPAD_LEFT:
                                int scrollWidth = itemWidth * mPosition;
                                hsv_green.smoothScrollTo(scrollWidth,0);

                                if(EPGTypeListAdapter.mPosition == 0){//ltr
                                    iv_green_left.setVisibility(View.INVISIBLE);
                                }else if(EPGTypeListAdapter.mPosition == mData.size() -1){//rtl
                                    iv_green_right.setVisibility(View.INVISIBLE);
                                }else{
                                    iv_green_left.setVisibility(View.VISIBLE);
                                    iv_green_right.setVisibility(View.VISIBLE);
                                }
                                break;
                        }
                    }
                }
                return false;
            }
        });

        gv_red.setLayoutParams(params);
        gv_red.setColumnWidth(itemWidth);
        gv_red.setNumColumns(size);

        gv_red.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if(event.getAction() == KeyEvent.ACTION_DOWN){
                    if(redAdapter.ismFocus()){
                        redAdapter.onMainKey(v,keyCode);

                        int mPosition = 0;
                        if(isRtl()){
                            //rtl布局下,GridView的位置顺序相反
                            mPosition = mData.size()-1-EPGTypeListAdapter.mPosition;
                        }else{
                            mPosition = EPGTypeListAdapter.mPosition;
                        }

                        //操作外套scrollView的滑动位置和两边箭头显示与隐藏
                        int scrollWidth = 0;
                        switch (keyCode){
                            case KeyEvent.KEYCODE_DPAD_RIGHT:
                                scrollWidth = itemWidth * mPosition;
                                //smoothScrollTo指滑动到的位置,smoothScrollBy指滑动的距离
                                hsv_red.smoothScrollTo(scrollWidth,0);

                                if(EPGTypeListAdapter.mPosition == mData.size()-1){//ltr
                                    iv_red_right.setVisibility(View.INVISIBLE);
                                }else if(EPGTypeListAdapter.mPosition == 0){//rtl
                                    iv_red_left.setVisibility(View.INVISIBLE);
                                }else{
                                    iv_red_left.setVisibility(View.VISIBLE);
                                    iv_red_right.setVisibility(View.VISIBLE);
                                }
                                break;
                            case KeyEvent.KEYCODE_DPAD_LEFT:
                                scrollWidth = itemWidth * mPosition;
                                hsv_red.smoothScrollTo(scrollWidth,0);

                                if(EPGTypeListAdapter.mPosition == 0){//ltr
                                    iv_red_left.setVisibility(View.INVISIBLE);
                                }else if(EPGTypeListAdapter.mPosition == mData.size() -1){//rtl
                                    iv_red_right.setVisibility(View.INVISIBLE);
                                }else{
                                    iv_red_left.setVisibility(View.VISIBLE);
                                    iv_red_right.setVisibility(View.VISIBLE);
                                }
                                break;
                        }
                    }
                }
                return false;
            }
        });

        gv_blue.setLayoutParams(params);
        gv_blue.setColumnWidth(itemWidth);
        gv_blue.setNumColumns(size);

        gv_blue.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if(event.getAction() == KeyEvent.ACTION_DOWN){
                    if(blueAdapter.ismFocus()){
                        blueAdapter.onMainKey(v,keyCode);

                        int mPosition = 0;
                        if(isRtl()){
                            //rtl布局下,GridView的位置顺序相反
                            mPosition = mData.size()-1-EPGTypeListAdapter.mPosition;
                        }else{
                            mPosition = EPGTypeListAdapter.mPosition;
                        }

                        //操作外套scrollView的滑动位置和两边箭头显示与隐藏
                        int scrollWidth = 0;
                        switch (keyCode){
                            case KeyEvent.KEYCODE_DPAD_RIGHT:
                                scrollWidth = itemWidth * mPosition;
                                //smoothScrollTo指滑动到的位置,smoothScrollBy指滑动的距离
                                hsv_blue.smoothScrollTo(scrollWidth,0);

                                if(EPGTypeListAdapter.mPosition == mData.size()-1){//ltr
                                    iv_blue_right.setVisibility(View.INVISIBLE);
                                }else if(EPGTypeListAdapter.mPosition == 0){//rtl
                                    iv_blue_left.setVisibility(View.INVISIBLE);
                                }else{
                                    iv_blue_left.setVisibility(View.VISIBLE);
                                    iv_blue_right.setVisibility(View.VISIBLE);
                                }
                                break;
                            case KeyEvent.KEYCODE_DPAD_LEFT:
                                scrollWidth = itemWidth * mPosition;
                                hsv_blue.smoothScrollTo(scrollWidth,0);

                                if(EPGTypeListAdapter.mPosition == 0){//ltr
                                    iv_blue_left.setVisibility(View.INVISIBLE);
                                }else if(EPGTypeListAdapter.mPosition == mData.size() -1){//rtl
                                    iv_blue_right.setVisibility(View.INVISIBLE);
                                }else{
                                    iv_blue_left.setVisibility(View.VISIBLE);
                                    iv_blue_right.setVisibility(View.VISIBLE);
                                }
                                break;
                        }
                    }
                }
                return false;
            }
        });
        initUIValue();

    }

    int firstSeled = 0;//第一个颜色默认选中的位置
    public void initUIValue(){
        selectIndex[0] = getSelectGrid("orange1");
        EPGTypeListAdapter.mPosition = selectIndex[0];
        epgList.requestFocus();

        if(isRtl()){
            firstSeled = mData.size()-1-selectIndex[0];
        }else{
            firstSeled = selectIndex[0];
        }

        if(selectIndex[0] != 0){//本判断条件为阿拉伯语时添加
            myHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    epgList.setSelection(selectIndex[0]);
                    //这一句不能用myHandler.postAtFrontOfQueue
                    hsv_green.smoothScrollTo(itemWidth * firstSeled,0);
                }
            },100);
        }

        //arrow display
        if(selectIndex[0] == 0){
            iv_green_left.setVisibility(View.INVISIBLE);
        }else if(selectIndex[0] == mData.size()-1){
            iv_green_right.setVisibility(View.INVISIBLE);
        }else{
            iv_green_right.setVisibility(View.VISIBLE);
            iv_green_left.setVisibility(View.VISIBLE);
        }
    }

    /*
    * 获取各个颜色选中值的位置
    * */
    public int getSelectGrid(String key){
        String offString = mContext.getResources().getString(R.string.nav_sleep_off);
        for(int i=0;i= 0){
                        final int index = i-1;
                        gridViewList.get(index).requestFocus();
                        selectIndex[index] = getSelectGrid(keyStr[index]);
                        EPGTypeListAdapter.mPosition = selectIndex[index];
                        int firstIndex = 0;
                        if(isRtl()){
                            firstIndex = mData.size()-1-selectIndex[index];
                        }else{
                            firstIndex = selectIndex[index];
                        }
                        myHandler.postAtFrontOfQueue(new Runnable() {
                            @Override
                            public void run() {
                                gridViewList.get(index).setSelection(selectIndex[index]);
                            }
                        });

                        if(i == 2){
                            hsv_red.smoothScrollTo(itemWidth*firstIndex,0);
                            if(selectIndex[index] == 0){
                                iv_red_left.setVisibility(View.INVISIBLE);
                            }else if(selectIndex[index] == mData.size()-1){
                                iv_red_right.setVisibility(View.INVISIBLE);
                                //左箭头初始状态不显示,当按上键到当前颜色的选中位置(非第一个位置)时,左箭头要显示出来
                                iv_red_left.setVisibility(View.VISIBLE);
                            }else{
                                iv_red_right.setVisibility(View.VISIBLE);
                                iv_red_left.setVisibility(View.VISIBLE);
                            }
                        }else if(i==1){
                            hsv_green.smoothScrollTo(itemWidth*firstIndex,0);
                            if(selectIndex[index] == 0){
                                iv_green_left.setVisibility(View.INVISIBLE);
                            }else if(selectIndex[index] == mData.size()-1){
                                iv_green_right.setVisibility(View.INVISIBLE);
                                //左箭头初始状态不显示,当按上键到当前颜色的选中位置(非第一个位置)时,左箭头要显示出来
                                iv_green_left.setVisibility(View.VISIBLE);
                            }else{
                                iv_green_right.setVisibility(View.VISIBLE);
                                iv_green_left.setVisibility(View.VISIBLE);
                            }
                        }
                    }
                }
                if(gridViewIndex > 0){
                    gridViewIndex --;
                }
                return true;
            default:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }
}

布局文件:



    
        
            
            
        
        
            
            
                
                    

                    
                
            
            
        
    

    
        
            
            
        
        
            
            
                
                    

                    
                
            
            
        
    
    
        
            
            
        
        
            
            
                
                    

                    
                
            
            
        
    


EPGTypeListAdapter代码:

package com.example.demo1.demo1.epgtype;

import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.demo1.demo1.R;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

/**
 * Created by wangchunmei.ex on 2018/10/12.
 */

public class EPGTypeListAdapter extends BaseAdapter {
    private static final String TAG = "EPGTypeListAdapter";
    List mData;
    Context mContex;
    EPGSaveValue sv;
    GridView mList;
    List gridViewList;
    ViewHolder mViewHoler;
    static int mPosition = 0;
    private static boolean mFocus = true;
    int source = 0;
    String offString = "";

    EPGTypeListAdapter(Context context){
        mContex = context;
        sv = EPGSaveValue.getInstance(context);
    }

    EPGTypeListAdapter(Context context,GridView mainList){
        mContex = context;
        sv = EPGSaveValue.getInstance(context);
        mList = mainList;
        mPosition = 0;
        mFocus = true;
        offString = mContex.getResources().getString(R.string.nav_sleep_off);
    }

    public boolean ismFocus(){
        return mFocus;
    }

    @Override
    public int getCount() {
        if(mData == null)
            return 0;
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData == null? null : position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null){
            mViewHoler = new ViewHolder();
            convertView = LayoutInflater.from(mContex).inflate(R.layout.epg_type_item,null);
            mViewHoler.mTextView = (TextView)convertView.findViewById(R.id.epg_type_name);
            convertView.setTag(mViewHoler);
        }else{
            mViewHoler = (ViewHolder)convertView.getTag();
        }
        if(mData != null && mData.size() >0){
            if(null != mData.get(position) && mData.get(position).data.length() != 0){
                if(mViewHoler.mTextView != null){
                    mViewHoler.mTextView.setText(mData.get(position).data);
                    //每个颜色显示选中的类型值,并将选中的项设置成蓝色
                    if(sv.readBooleanValue(mData.get(position).data,false) && sv.readIntValue(mData.get(position).data,0)==source){
                        mViewHoler.mTextView.setTextColor(mContex.getResources().getColor(R.color.app_panel_tab_select));
                        if(source == 1){
                            EPGTypeDialog.tv_orange.setText(mData.get(position).data);
                        }else if(source == 2){
                            EPGTypeDialog.tv_red.setText(mData.get(position).data);
                        }else if(source == 3){
                            EPGTypeDialog.tv_blue.setText(mData.get(position).data);
                        }
                    }else{
                        //将每个颜色中其他颜色已经选中的类型置灰,其他类型恢复默认
                        if(source == 1){
                            selectIndex[1] = getSelectGrid(keyStr[1]);
                            selectIndex[2] = getSelectGrid(keyStr[2]);
                            if((position == selectIndex[1] || position == selectIndex[2]) && position != 0){
                                mViewHoler.mTextView.setTextColor(mContex.getResources().getColor(R.color.card_meta_text_color_disabled));
                                mViewHoler.mTextView.setBackgroundColor(mContex.getResources().getColor(R.color.banner_basic_divider));
                            }else{
                                mViewHoler.mTextView.setTextColor(mContex.getResources().getColor(R.color.white));
                            }
                        }else if(source == 2){
                            selectIndex[0] = getSelectGrid(keyStr[0]);
                            selectIndex[2] = getSelectGrid(keyStr[2]);
                            if((position == selectIndex[0] || position == selectIndex[2]) && position != 0){
                                mViewHoler.mTextView.setTextColor(mContex.getResources().getColor(R.color.card_meta_text_color_disabled));
                                mViewHoler.mTextView.setBackgroundColor(mContex.getResources().getColor(R.color.banner_basic_divider));
                            }else{
                                mViewHoler.mTextView.setTextColor(mContex.getResources().getColor(R.color.white));
                            }
                        }else if(source == 3){
                            selectIndex[0] = getSelectGrid(keyStr[0]);
                            selectIndex[1] = getSelectGrid(keyStr[1]);
                            if((position == selectIndex[0] || position == selectIndex[1]) && position != 0){
                                mViewHoler.mTextView.setTextColor(mContex.getResources().getColor(R.color.card_meta_text_color_disabled));
                                mViewHoler.mTextView.setBackgroundColor(mContex.getResources().getColor(R.color.banner_basic_divider));
                            }else{
                                mViewHoler.mTextView.setTextColor(mContex.getResources().getColor(R.color.white));
                            }
                        }
                    }
                }
            }
        }

        return convertView;
    }

    class ViewHolder{
        TextView mTextView;
    }

    int[] selectIndex = new int[3];
    String[] keyStr = {"orange1","red2","blue3"};
    private Handler myHandler = new Handler();
    public int getSelectGrid(String key){
        for(int i=0;i gridList){
        this.gridViewList  = gridList;
    }

    public void setSource(int source) {
        this.source = source;
    }

    public List getEPGData() {
        return mData;
    }

    public void setEPGData(List mData) {
        this.mData = mData;
    }

    /*
    * 获取TYPE的值
    * */
    public List loadEPGFilterTypeData(String contry) {
        String[] mType = null;
        mType = mContex.getResources().getStringArray(R.array.nav_epg_filter_type);
        List mDataGroup = new ArrayList();
        for(int i=0;i list = new ArrayList();
        for(int i=0;i<3;i++){
            if(i != source-1){
                list.add(getSelectGrid(keyStr[i])+"");
            }
        }
        Collections.sort(list);

        switch (keyCode){
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                if(!isRtl()){
                    if(mPosition >= mList.getAdapter().getCount()-1){
                    }else{
                        mPosition++;
                        for(int j=0;j=0;j--){
                            //当当前位置已经选中,且不等于第一个位置时,
                            if(mPosition == Integer.parseInt(list.get(j)) && mPosition != 0){
                                if(getSelectPosition(source) == 3){
                                    mPosition -= 2;
                                }else{
                                    mPosition -=1;
                                }
                            }
                        }
                        myHandler.postAtFrontOfQueue(new Runnable() {
                            @Override
                            public void run() {
                                mList.setSelection(mPosition);
                            }
                        });
                    }
                }
                break;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                if(!isRtl()){
                    if(mPosition <=0){

                    }else{
                        mPosition--;
                        //左键的移动位置与右键正好相反
                        for(int j=list.size()-1;j>=0;j--){
                            //当当前位置已经选中,且不等于第一个位置时,
                            if(mPosition == Integer.parseInt(list.get(j)) && mPosition != 0){
                                if(getSelectPosition(source) == 3){
                                    mPosition -= 2;
                                }else{
                                    mPosition -=1;
                                }
                            }
                        }
                        myHandler.postAtFrontOfQueue(new Runnable() {
                            @Override
                            public void run() {
                                mList.setSelection(mPosition);
                            }
                        });
                    }
                }else{
                    if(mPosition >= mList.getAdapter().getCount()-1){
                    }else{
                        mPosition++;
                        for(int j=0;j 
 

你可能感兴趣的:(视频,图像,音乐,效果)