给android layout 添上state的翅膀

在android中,可以很容易给一个视图的外观加上state,从而反映行为状态比如:激活、选中、悬浮等。但是对于视图布局的动态调整,比如说某一状态,需要显示按钮,下一个状态,不需要显示这个按钮,就显得苍白无力。

这种情况,大家会说我去改一下按钮的可见度就ok了呀。的确是这样,但是涉及到多个状态、多个控件的时候是不是很麻烦?现有解决办法主要问题有:

(1)      多状态、多组件的难于管理。

(2)      没用的组件只是看不见了,但是还存在,浪费资源。

有没有更好的方法?有,那就是引入state。

先看截图:

 这个是默认状态的:

点击show clicked按钮,变成:

最后,点击show all,切换到all状态:

这里面有两个组件: 按钮和文本框,三种状态:default、clicked、all。default下显示文本框,clicked下显示按钮,all下显示所有。

怎么做的?

首先需要定义状态

在状态视图的layout上用tractor:states定义所有状态,tractor:currentState指定默认状态。如下面代码所示:

<LinearLayout         xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tractor="http://schemas.tractorframework.com/tractor"
    ...
    tractor:states="default,clicked,all"
    tractor:currentState="default"
    tractor:layout="activity_main" >   
    

还有一个标签是trantor:layout,这个是用来指定状态视图的layout的,在状态切换的时候,需要这个参数来获得layout,重新构造整个视图。也就是说状态视图的layout都需要

一个单独的layout文件来定义。有点小不方便,但是对于大量的可见度管理来说,可以接受,您说呢?

在控件上声明对应状态

在视图控件上使用tractor:includeIn来表明该控件存在于哪些状态下,或者用tractor:excludeFrom来指定不存在于哪些状态。下面是例子程序的两个控件的状态声明:

 <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tractor:includeIn="clicked,all"
        android:text="hello clicked state"
        />

    <EditText 
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tractor:excludeFrom="clicked"
        android:text="hello default state" />

按钮存在于clicked,all两个状态,文本框不存在于clicked状态,也就是说存在于default和all状态。

状态切换

上面都是定义和声明,是不是很简单?状态切换也不复杂,在上面例子上,最上面的三个按钮就是切换状态用的,它们被点击后,就会去切换对应状态。比如show clicked按钮点击就会去切换到clicked状态,代码是这样的:

    public void switchToClicked(View v)
    {
        View root = findViewById(R.id.root);
        sf.getViewState(root).setCurrentState("clicked");
    }

首先得到状态视图,其次得到状态试图对应的ViewState去设置当前状态。一切很容易操作的了,但是大家会说sf是什么,看下面。

最核心的是加入状态支持,在Activity设置视图之前,重新设置LayoutInflater的Factory2工厂,这个在sdk版本11才有哦。这个sf就是加入了状态支持的Factory2工厂实例。

例子程序的Activity是这样构造的:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        createInflator();
        setContentView(R.layout.activity_main);
    }
    
    
    private void createInflator()
    {
        LayoutInflater inflater = LayoutInflater.from(this);
        sf = new StateFactory(inflater);
        inflater.setFactory2(sf);
    }

核心代码就是StateFactory。这个地方可以下载整个例子程序,里面有StateFactory的代码。整个例子只是演示用的,StateFactory实现的也有不妥的地方,但是我们可以看到android支持视图状态的可能性。有了state,android 视图代码又会好写很多,一切目标:简单。您说呢 ?

原文地址:https://www.cnblogs.com/simplevita/p/3928482.html