Android TV 开发有关PopupWindow的KeyListener(手机也能用)

来源:互联网 发布:淘宝招募令 编辑:程序博客网 时间:2024/05/22 00:12

      转载请标明原地址:http://blog.csdn.net/gaolei1201/article/details/38586851         

     现在这个公司主要是做智能电视视频方面。有硬件电视盒子,APP开发,源码二次开发、Launcher开发等。这几天做了一个播放界面弹出设置菜单效果,过程挺曲折的,也挺实用的,就和大家分享一下!如图,点击遥控器上下键使蓝框可以上下移动,点击左右键可以改变内容,按菜单键显示此窗口,再按菜单键和返回键退出,UI效果够酷吧。

        磊磊很自然的想到了用PopupWindow,但是问题来了,Activity的pulib  void onKeyDown()方法已经被占用,写了许多切换频道等逻辑。因为有多个播放界面需要此功能,所以要把它独立出来写一个类。如何获取此PopupWindow的焦点是一个问题,在网上搜了不少有关知识,都是针对手机的,没有理想的有关监听PopupWindow的上下左右,还有菜单键,返回键的KeyListener,但是在搜索的过程中也找到了思路。PopupWindow父类不是View,因此没有KeyListener。那怎么办呢?方方法总会有的(其实最后发现PopupWindow不太好用,像这个功能直接在xml中多添加一个布局就行,让她显示或隐藏,So Easy)。

     我们可以获取PopupWindow里面View的焦点,然后监听它的KeyListener,如"画面比例"这个TextView。

共有两种方法:

    一、自定义TextView,让这个TextView获取焦点及KeyListener.部分代码如下:


public class CustomTextView extends TextView {    //     自定义TextView让它获取焦点,监听它的KeyListener,相当于是PopupWindow的KeyListener//     选择任意一个子控件设置它的焦点,并且不能设置父控件如LinearLayout焦点,因为这样会使子控件焦点无效//     android:focusable="true" //     android:focusableInTouchMode="true"        private static String TAG = "CustomTextView";    private static int ratioflag = 0, bitratesflag = 0, focusflag = 0;    private static String[] display_ratios_array = new String[] { "全屏", "4:3",            "16:9" };    private static String[] display_bitrates_array = new String[] { "标清", "高清" };    private static ImageView image_focus;    private static TextView display_ratios, display_bitrates,            text_display_scale, text_display_bitrates;    private static Animation focus_down_anim;    private static Animation focus_up_anim;    public CustomTextView(Context context) {        super(context);        // TODO Auto-generated constructor stub    }    public CustomTextView(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub    }    public static void InitMenuPopupWindow(Context context,            PopupWindow mPopupWindow, View popup_view) {        focus_down_anim = AnimationUtils.loadAnimation(context,                R.anim.popup_menu_sub_layout_focus_down);        focus_up_anim = AnimationUtils.loadAnimation(context,                R.anim.popup_menu_sub_layout_focus_up);        /* 设置触摸外面时消失 */        mPopupWindow.setOutsideTouchable(true);        /* 设置系统动画 */        mPopupWindow.setAnimationStyle(android.R.style.Animation_Toast);        mPopupWindow.setFocusable(true);        display_ratios = (TextView) popup_view.findViewById(R.id.display_scale);        display_bitrates = (TextView) popup_view                .findViewById(R.id.display_bitrates);        text_display_scale = (TextView) popup_view                .findViewById(R.id.text_display_scale);        text_display_bitrates = (TextView) popup_view                .findViewById(R.id.text_display_bitrates);        text_display_scale.requestFocus();        image_focus = (ImageView) popup_view.findViewById(R.id.image_focus);    }    public boolean onKeyDown(int keyCode, KeyEvent event) {        switch (keyCode) {        case KeyEvent.KEYCODE_DPAD_UP:              if (focusflag == 1) {                image_focus.startAnimation(focus_up_anim);            }            focusflag = focusflag - 1;            if (focusflag < 0) {                focusflag = 0;            }            return true;        case KeyEvent.KEYCODE_DPAD_DOWN:             if (focusflag == 0) {                image_focus.startAnimation(focus_down_anim);            }            focusflag = focusflag + 1;            if (focusflag > 1) {                focusflag = 1;            }            return true;        case KeyEvent.KEYCODE_DPAD_LEFT:            if (focusflag == 0) {                ratioflag--;                if (ratioflag >= 0) {                    display_ratios.setText(display_ratios_array[ratioflag]);                } else {                    ratioflag = 0;                }            } else {                bitratesflag--;                if (bitratesflag >= 0) {                    display_bitrates                            .setText(display_bitrates_array[bitratesflag]);                } else {                    bitratesflag = 0;                }            }            return true;        case KeyEvent.KEYCODE_DPAD_RIGHT:            if (focusflag == 0) {                ratioflag++;                if (ratioflag <= display_ratios_array.length - 1) {                    display_ratios.setText(display_ratios_array[ratioflag]);                } else {                    ratioflag = display_ratios_array.length - 1;                }            } else {                bitratesflag++;                Log.d(TAG, "bitratesflag -----------right----------------"                        + bitratesflag);                if (bitratesflag <= display_bitrates_array.length - 1) {                    display_bitrates                            .setText(display_bitrates_array[bitratesflag]);                } else {                    bitratesflag = display_bitrates_array.length - 1;                }            }            return true;        case KeyEvent.KEYCODE_BACK:            Log.d(TAG, "back---------------------------");            if (MainActivity.mPopupWindow != null) {                MainActivity.mPopupWindow.dismiss();            }            return true;        case KeyEvent.KEYCODE_MENU:            Log.d(TAG, "menu---------------------------");            if (MainActivity.mPopupWindow != null) {                MainActivity.mPopupWindow.dismiss();            }            return true;        default:            // do nothing here            return false;        }    }}



二、监听PopupWindow里面任意一个View的KeyListener, 部分代码如下


public class MainActivity extends Activity {    private String TAG = "MainActivity";    private ImageView image_focus;    private TextView display_ratios, display_bitrates, text_display_scale,            text_display_bitrates;    private LinearLayout popup_menu_display_scale, popup_menu_display_bitrates;    private Animation focus_down_anim, focus_up_anim;    private String[] display_bitrates_array = new String[] { "标清", "高清","流畅" };    private String[] display_ratios_array = new String[] { "全屏", "4:3", "16:9" };    private int ratioflag = 0, bitratesflag = 0, focusflag = 0;    private Button button;    private PopupWindow mPopupWindow;//    public static ArrayList<String> bitratesList = new ArrayList<String>();//    public static ArrayList<String> ratiosList = new ArrayList<String>();    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        View popup_view = LayoutInflater.from(this).inflate(                R.layout.popup_layout, null);            button = (Button) findViewById(R.id.show);                image_focus = (ImageView) popup_view.findViewById(R.id.image_focus);        display_ratios = (TextView) popup_view.findViewById(R.id.display_scale);        display_bitrates = (TextView) popup_view                .findViewById(R.id.display_bitrates);        text_display_scale = (TextView) popup_view                .findViewById(R.id.text_display_scale);        //text_display_scale.requestFocus();        text_display_bitrates = (TextView) popup_view                .findViewById(R.id.text_display_bitrates);        focus_down_anim = AnimationUtils.loadAnimation(this,                R.anim.popup_menu_sub_layout_focus_down);        focus_up_anim = AnimationUtils.loadAnimation(this,                R.anim.popup_menu_sub_layout_focus_up);        popup_menu_display_scale = (LinearLayout) popup_view                .findViewById(R.id.popup_menu_display_scale);        //        for (int i = 0; i < display_ratios_array.length; i++) {//            ratiosList.add(display_ratios_array[i]);//        }//        for (int i = 0; i < display_bitrates_array.length; i++) {//            bitratesList.add(display_bitrates_array[i]);//        }                                button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View arg0) {                // TODO Auto-generated method stub                mPopupWindow.showAtLocation(findViewById(R.id.show),                        Gravity.CENTER, 0, 0);            }        });        // 这里主要针对Android TV开发 ,只有遥控器,所以Key监听事件用的比较多,和手机不一样。        //这个地方最关键必须是设置popup_view里面的一个控件KeyListener,不能是布局如popup_menu_display_scale,        //也不能是popup_view(网上许多这样说法,是行不通的),        text_display_bitrates.setOnKeyListener(new View.OnKeyListener() {            @Override            public boolean onKey(View v, int keyCode, KeyEvent event) {                // TODO Auto-generated method stub                switch (keyCode) {                case KeyEvent.KEYCODE_DPAD_UP:                             if (focusflag == 1) {                        image_focus.startAnimation(focus_up_anim);                    }                    focusflag = focusflag - 1;                    if (focusflag < 0) {                        focusflag = 0;                    }                    return true;                case KeyEvent.KEYCODE_DPAD_DOWN:                                        if (focusflag == 0) {                        image_focus.startAnimation(focus_down_anim);                    }                    focusflag = focusflag + 1;                    if (focusflag > 1) {                        focusflag = 1;                    }                    return true;                case KeyEvent.KEYCODE_DPAD_LEFT:                                       if (focusflag == 0) {                        ratioflag--;                                                if (ratioflag >= 0) {                            display_ratios.setText(display_ratios_array[ratioflag]);                        } else {                            ratioflag = 0;                        }                    } else {                        bitratesflag--;                                                if (bitratesflag >= 0) {                            display_bitrates                                    .setText(display_bitrates_array[bitratesflag]);                        } else {                            bitratesflag = 0;                        }                    }                    return true;                case KeyEvent.KEYCODE_DPAD_RIGHT:                                      if (focusflag == 0) {                        ratioflag++;                                                if (ratioflag <= display_ratios_array.length - 1) {                            display_ratios.setText(display_ratios_array[ratioflag]);                        } else {                            ratioflag = display_ratios_array.length - 1;                        }                    } else {                        bitratesflag++;                                                if (bitratesflag <= display_bitrates_array.length - 1) {                            display_bitrates                                    .setText(display_bitrates_array[bitratesflag]);                        } else {                            bitratesflag = display_bitrates_array.length - 1;                        }                    }                    return true;                case KeyEvent.KEYCODE_BACK:                                      if (mPopupWindow != null) {                        mPopupWindow.dismiss();                    }                    return true;                case KeyEvent.KEYCODE_MENU:                                      showMenuWindow();                    return true;                }                return false;            }        });        mPopupWindow = new PopupWindow(popup_view, 700, 400);        mPopupWindow.setFocusable(true);        mPopupWindow.setAnimationStyle(android.R.style.Animation_Toast);    }//    @Override//    public boolean onMenuOpened(int featureId, Menu menu) {        // 截获菜单事件//        // TODO Auto-generated method stub//        showMenuWindow();//        return false;        // 返回为true 则显示系统menu//        //    }////    @Override//    public boolean onCreateOptionsMenu(Menu menu) {//        // TODO Auto-generated method stub////        menu.add("menu");// 必须创建一项//        return super.onCreateOptionsMenu(menu);//        //    }      public boolean onKeyDown(int kCode, KeyEvent kEvent) {        switch (kCode) {        case KeyEvent.KEYCODE_BACK:                 MainActivity.this.finish();            return true;                }        return false;    }     private void showMenuWindow()        {                        if (mPopupWindow.isShowing())            {                mPopupWindow.dismiss();            }else{                mPopupWindow.showAtLocation(findViewById(R.id.show),                        Gravity.CENTER, 0, 0);                 }        }}



                                      源码地址,点击下载......

0 0
原创粉丝点击