android开发 gridview的item与子控件焦点问题

最近项目中用到了gridview,顺带对gridview的item与子控件焦点问题进行小小的研究比较下;

项目需求:在simphone手持把枪上通过方向按钮实现gridview的菜单选择;


实现方法1:在子布局中写入button的background属性,在gridview中定义descendantFocusability为afterDescendants,让button优先获得焦点

ViewGroup.FOCUS_AFTER_DESCENDANTS:表示item的子控件优先于item获得焦点;

ViewGroup.FOCUS_BEFORE_DESCENDANTS:表示item优先于其子控件获得焦点

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:gravity="center"

    android:orientation="vertical">

    <Button

        android:id="@+id/btn"

        style="@style/large_white_text"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:background="@drawable/bbuton_primary_rounded"

        android:text="入库"/>

</LinearLayout>

    <GridView

        android:id="@+id/gridView1"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:numColumns="2"

        android:horizontalSpacing="12dp"

        android:verticalSpacing="12dp"

        android:descendantFocusability="afterDescendants"

        android:paddingTop="38dp"

        android:paddingLeft="12dp"

        android:paddingRight="12dp">

    </GridView>

结果:大致达到要求,只是存在问题:1.菜单项过多的时候,通过方向键向下选择菜单,gridview无法自动滚动
为此,又通过以下方法:在适配器getview中,监听btn的状态,通过状态变化,改变gridview滚动位置。

holder.btn.setOnFocusChangeListener(new OnFocusChangeListener() {

@Override

public void onFocusChange(View v, boolean hasFocus) {

if(hasFocus){

btnFocusChange.onFocusChange(pos,btn);

}

}

});

adapter.setOnBtnFocusChange(new GridViewAdapter.BtnFocusChange() {

@Override

public void onFocusChange(int pos, Button btn) {

Log.e("onFocusChange","" + pos);

btn.setSelected(true);

btn.setFocusable(true);

gridView.setSelection(pos);

}

});

结果:现象有改善,只是还是有问题:1.若有滚动,左右方向键需按两次才能切换菜单(原因可能与 gridView .setSelection(pos)有关,毕竟这句代码焦点是gridview的item项~而不是其子控件)2.若菜单在完全不可见的情况下,方向键无法选择得到,因此gridview也不可能
滚动;问题多多,所以此路不通,何不换种思路,借鉴listview的启示。


实现方法2:让gridview的item获得焦点,设置listSelector属性gridview_item_selector,item文件下设置android:descendantFocusability="blocksDescendants"

ListView默认情况

当item有焦点时,item上的button等子控件获取不到焦点;

当子控件有焦点时,item无焦点无法响应onItemClick事件

    <GridView

        android:id="@+id/gridView1"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:numColumns="2"

        android:horizontalSpacing="12dp"

        android:verticalSpacing="12dp"

        android:paddingTop="38dp"

        android:listSelector="@drawable/gridview_item_selector"

        android:paddingLeft="12dp"

        android:paddingRight="12dp">

    </GridView>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:gravity="center"

    android:orientation="vertical" 

    android:padding="1dp"

    android:descendantFocusability="blocksDescendants">


    <Button

        android:id="@+id/btn"

        style="@style/large_white_text"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:background="@drawable/bbuton_primary_rounded"

        android:text="入库" 

        android:gravity="center"/>


</LinearLayout>

gridview_item_selector.xml如下

<?xmlversion="1.0"encoding="utf-8"?>

<selectorxmlns:android="http://schemas.android.com/apk/res/android">


    <itemandroid:state_selected="true">

        <shapeandroid:shape="rectangle">

            <solidandroid:color="#FFE1E1E1"/>

            <strokeandroid:width="1dp"android:color="@color/black"/>

            <cornersandroid:radius="@dimen/radius"/>

        </shape>

    </item>

    

    <itemandroid:state_pressed="true">

        <shapeandroid:shape="rectangle">

            <solidandroid:color="#FFE1E1E1"/>

            <strokeandroid:width="1dp"android:color="@color/black"/>

            <cornersandroid:radius="@dimen/radius"/>

        </shape>

    </item>

    

    <itemandroid:state_focused="true">

        <shape>

            <solidandroid:color="#FFE1E1E1"/>

            <strokeandroid:width="1dp"android:color="@color/black"/>

            <cornersandroid:radius="@dimen/radius"/>

        </shape>

    </item>

    

    <itemandroid:state_active="true">

        <shape>

            <solidandroid:color="#FFE1E1E1"/>

        </shape>

    </item>

    

    <item>

        <shapeandroid:shape="rectangle">

            <solidandroid:color="@color/transparent"/>

        </shape>

    </item>


</selector>

结果:基本实现用方向键选取菜单时,gridview会随选择滚动,点击OK键时,能响应gridView.setOnItemClickListener(this)事件,但是此时发现触屏下,不用方向键手动点击触发菜单时,没响应(原因:button抢去了gridview的item点击事件)
解决:最后无奈将button控件改为TextView,完成了项目需求。

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:gravity="center"

    android:orientation="vertical" 

    android:padding="1dp"

    android:descendantFocusability="blocksDescendants">


    <TextView

        android:id="@+id/btn"

        style="@style/large_white_text"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:background="@drawable/bbuton_primary_rounded"

        android:text="入库" 

        android:gravity="center"/>

</LinearLayout>

综上所述,选对实现方法是可以事半功倍的,若是一开始就用方法2,也就不用纠结耗费半天时间;写出来与大家分享,免得像我一样绕弯。还有最近刚好做到原因单选,本想用radiobutton实现,现在好像也可用gridview试试:)




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值