Android ListView selected默认选中第一个position解决办法

Android ListView selected默认选中第一个position解决办法

  • 最近在做一个实验键盘完成一个购物的流程,其中就涉及到使用键盘方向键控制ListView中的Item选中状态。本以为通过实现OnItemSelectedListener接口就可以实现功能,事实上并不能满足需求。

  • 出现的问题是这样的: 每次进入页面,都会选中第一条,但是这时按下方向键“下”也会选中第一条,但是这时候却不会触发OnItemSelectedListener接口中的onItemSelected方法,所以使用方向键“下”首次无法监听到事件。到处百度、谷歌了很久未果,就自定义了一个ListView,解决了问题。

  • 之所以出现默认选中position==0,肯定出在焦点问题上。虽然不知道google当时为什么默认选中第一个,但是确实给开发者造成了一定的困扰,有时候我们不想要那么智能,灵活性好我们能做的会更多更好。既然是焦点问题,我们就要重写

protected void onFocusChanged(boolean gainFocus, int direction,Rect previouslyFocusedRect)

方法。出现问题的地方只是在position==0position==size-1,即首末两个item,我们只需要关注这两个即可,也就是

getSelectedItemPosition()
   == 0 || getSelectedItemPosition() == getCount()-1

再去执行我们处理的方法就行了。
- 思路有了,下面上代码:

package com.wz.tv;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

/**
 * Created by zhangzhenguo on 2017/2/17.
 * 支持键盘操作的ListView
 */

public class TVListView extends ListView {
    private EventListener mEventListener;

    /**
     * 当前选中的item
     */
    private int mSelectPosition = -1;
    /**
     * 失去焦点时选中的position
     */
    private int mLastSelectPosition = -1;

    public TVListView(Context context) {
        this(context,null);
    }

    public TVListView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public TVListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        EventItemSelectedListener mEventItemSelectedListener = new EventItemSelectedListener();
        this.setOnItemSelectedListener(mEventItemSelectedListener);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (mEventListener != null) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
                mEventListener.onEnterEvent(mSelectPosition);
            }
        }
        return super.dispatchKeyEvent(event);
    }

    @Override
    protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
        if (mEventListener == null) {
            return;
        }
        if (gainFocus) {// TODO 为了解决selected事件首次进入即position==0时不执行的问题
            if (getSelectedItemPosition() == 0 || getSelectedItemPosition() == getCount()-1) {
                //item == 0时,即列表第一条itemView获取焦点时
                if (mLastSelectPosition == -1 || mLastSelectPosition == 0){
                    Log.d("zzg","mLastSelectPosition:"+mLastSelectPosition);
                    mSelectPosition = getSelectedItemPosition();
                    setSelect();
                }
                //item == size-1,即列表最后一条itemView获取焦点时
                if (getSelectedItemPosition() == getCount()-1 && mLastSelectPosition == getCount() -1){
                    Log.d("zzg","mLastSelectPosition:"+mLastSelectPosition);
                    mSelectPosition = getSelectedItemPosition();
                    setSelect();
                }
            }
        }else {
            mLastSelectPosition = mSelectPosition;
            mSelectPosition = -1;
            mEventListener.onNextMenu(getSelectedItemPosition());
        }
    }

    /**
     * 回调select监听
     */
    private void setSelect(){
        final int[] location = new int[2];
        getSelectedView().getLocationOnScreen(location);
        mEventListener.onItemSelected(getSelectedItemPosition(),location[1]);
    }


    public class EventItemSelectedListener implements OnItemSelectedListener{

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, final int position, long id) {
            mSelectPosition = position;
            if (mEventListener != null && isFocused()) {
                setSelect();
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            mSelectPosition = -1;
        }

    }

    public void setOnEnterEventListener(EventListener eventListener){
        this.mEventListener = eventListener;

    }

    public EventListener getOnEnterEventListener(){
        return this.mEventListener;
    }

    public interface EventListener{
        /**
         * Enter键监听
         * @param position 当前点击的item position,只适用于键盘的Enter键,如果既想使用键盘Enter键又想用鼠标点击请直接实现OnItemClickListener接口
         */
        void onEnterEvent(int position);
        /**
         * item selected监听
         * @param position selected item position
         * @param rawY 当前选中ItemView 在屏幕中的y轴坐标
         */
        void onItemSelected(int position, float rawY);
        /**
         * 离开ListView时,记录当前选中的position
         * @param position 焦点离开ListView时选中的item position
         */
        void onNextMenu(int position);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值