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

      转载请标明原地址:Android TV 开发有关PopupWindow的KeyListener(手机也能用)_高磊的专栏-CSDN博客         

 

     现在这个公司主要是做智能电视视频方面。有硬件电视盒子,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);
     
            }

        }
}


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值