安卓动态加载布局

吐槽

这周就写了一点点项目,因为马上要考试了啊啊啊啊,啥都不会,心塞塞哇哇哇。但是把项目中动态加载布局这块学习了一下,把项目这块写了,然后还学了下如何动态添加item这块。

什么叫动态布局

这里写图片描述

这就是动态加载布局,根据我选择的卡片类型,创建不同的布局,加载到下面
动态布局就是动态加载的布局啊emmmmmmm
有动态布局肯定有相应的静态布局
那两者有什么区别啊

静态布局是之前就写好的,直接加载出来的布局—————–就是实现定义好的,就是你在xml里面写好的,绑定好的布局

动态布局就是在程序运行时候根据不同的情况然后再加载的,比如要点击这个按钮要替换一部分布局

xml里面定义布局的时候其实就两类东西
1这个布局和父布局的关系
2这个布局自身的属性定义

如果我们要动态加载布局的话,也就是通过这改变两个方面去处理的,可以通过java代码的方式,或者LayoutInflater 来间接加载。

动态改变布局java方式

控件的自身属性的改变–java代码里面之间改就好了

button.setText("button");
textView.setText("Some text");

类似上面这种方式,改变控件的属性

动态布局的父布局规则改变

是通过父布局的LayoutParams对象来实现的。
现在我们要新建三个LayoutParams对象,分别对应RelativeLayout,Button,和TextView的父布局规则。

LinearLayout.LayoutParams relativeLayout_parent_params
                = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);

RelativeLayout.LayoutParams button_parent_params
                = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);

RelativeLayout.LayoutParams text_parent_params
                = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);

button_parent_params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
text_parent_params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

因为relativeLayout的父布局是LinearLayout,所以调用的是LinearLayout.LayoutParams,下面两个同理。创建一个LayoutParams对象时,要在构造方法输入宽高的参数。至于其他的父布局规则,用addRule方法就行了,xml中对应的规则属性在父布局的LayoutParams类中都有对应的常量。
最后一步,就是将其添加进布局了

relativerLayout.addView(button,button_parent_params);
relativerLayout.addView(textView,text_parent_params);
rootLayout.addView(relativerLayout,relativeLayout_parent_params);

父布局的addView方法,就可以将控件和规则和在一起

 protected void dynamic_add(){
        LinearLayout rootLayout = (LinearLayout)findViewById(R.id.root_layout);

        RelativeLayout relativerLayout = new RelativeLayout(this);
        Button button = new Button(this);
        TextView textView = new TextView(this);

        button.setText("button");
        textView.setText("Some text");

        LinearLayout.LayoutParams relativeLayout_parent_params
                = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
        RelativeLayout.LayoutParams button_parent_params
                = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
        RelativeLayout.LayoutParams text_parent_params
                = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);

        button_parent_params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        text_parent_params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

        relativerLayout.addView(button,button_parent_params);
        relativerLayout.addView(textView,text_parent_params);
        rootLayout.addView(relativerLayout,relativeLayout_parent_params);
    }

动态加载布局LayoutInflater 来间接加载

什么叫LayoutInflater

这个是个抽象类
在文档中如下声明:
public abstract class LayoutInflater extends Object
Layout inflation是在android系统中使用的术语,当XML布局资源被解析并转换成View对象时会用到。

LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。

具体作用:
1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
2、对于一个已经载入的界面,就可以使用Activity.findViewById()方法来获得其中的界面元素。

获取LayoutInflater 实例的三种方式

1.LayoutInflater inflater = getLayoutInflater();  //调用Activity的getLayoutInflater()

2. LayoutInflater localinflater=  (LayoutInflater)context.getSystemService
                                             (Context.LAYOUT_INFLATER_SERVICE);
3. LayoutInflater inflater = LayoutInflater.from(context);   

使用它的inflate方法//用来动态加载布局的方法

这个有四个重载的方法(参数不一样)

public View inflate (int resource, ViewGroup root) 
public View inflate (XmlPullParser parser, ViewGroup root) 
public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot) 
public View inflate (int resource, ViewGroup root, boolean attachToRoot)

第一个传入的参数resourse是你想要加载的布局资源就是子布局
第二个传入的参数是指当前载入的视图要将要放入在层级结构中的根视图。也就是父布局
如果传入了第三个参数attachToRoot,那么它会决定视图在载入完成后是否附加到传入的根视图中去。
对于上面代码,指定了第二个参数 ViewGrouproot,当然你也可以设置为 null 值。

动态加载布局的步骤

准备的东西:
1主xml布局//里面有个被替换的布局 R.id.RelativeLayout1父布局
2 要替换的布局:R.id.ly_inflate 子布局

第一步:书写下主xml文件
第二步:写要替换的xml文件
第三步:替换

public class MainActivity extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        //获得LayoutInflater对象; 
        final LayoutInflater inflater = LayoutInflater.from(this);   
        //获得外部容器对象 
        final RelativeLayout rly = (RelativeLayout) findViewById(R.id.RelativeLayout1); 
        Button btnLoad = (Button) findViewById(R.id.btnLoad); 
        btnLoad.setOnClickListener(new OnClickListener() { 
            @Override 
            public void onClick(View v) { 
                //加载要添加的布局对象 
                LinearLayout ly = (LinearLayout) inflater.inflate( 
                        R.layout.inflate, null, false).findViewById( 
                        R.id.ly_inflate); 
                //设置加载布局的大小与位置 
                RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(   
                        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);   
                lp.addRule(RelativeLayout.CENTER_IN_PARENT);   
                rly.addView(ly,lp); 
            } 
        }); 
    } 
}

猜你喜欢

转载自blog.csdn.net/sakurakider/article/details/80873285