自定义控件之 - 自定义LinearLayout控件

转载请注明出处amoscxy的博客:https://mp.csdn.net/mdeditor/80151114

自定义控件之 - 自定义LinearLayout控件

1.1 引入布局include

  • 最终效果
    这里写图片描述

要创建这样的标题栏只需在界面中加入,两个Button和一个TextView,然后布局中摆放好就可以了,可这样却存在着一个问题,一般我们的程序中有可能有很多activity都需要这样的标题栏,如果在每个activity的布局中都编写一遍同样的标题栏代码,明显就会导致大量的代码重复,这个时候我们就可以使用引入布局的方式来解决这个问题

  • 实例目录
    这里写图片描述

  • title.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/title_bg">

    <Button
        android:id="@+id/title_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/back_bg"
        android:text="Back"
        android:textColor="#fff" />

    <TextView
        android:id="@+id/title_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Title Text"
        android:textColor="#fff"
        android:textSize="24sp" />

    <Button
        android:id="@+id/title_edit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/edit_bg"
        android:text="Edit"
        android:textColor="#fff" />

</LinearLayout>

可以看到,我们再LinearLayout中分别加入了两个Button和一个TextView,左边Button可以用于返回,右边Buttton可以用于编辑,中间的TextView则可以显示一段标题文本,android:background用于为布局或空间指定一个背景,可以使用颜色活图片来进行填充,这里备好3张图片:
- title_bg.png
这里写图片描述
- back_bg.png
这里写图片描述
- edit_bg.png
这里写图片描述
分别作为标题栏、返回按钮和编辑按钮的背景,另外在Button中我们使用了android:layout_margin这个属性,它可以指定控件在上下左右方向上偏移的距离,当然也可以使用android:layout_marginLeft和android:layoutTop等属性来单独指定控件在某个方向上偏移的距离

  • 使用标题栏
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <include layout="@layout/title"/>

</LinearLayout>

我们只需通过一行include语句就将标题栏布局引入进来

  • 最后别忘了在MainActivity中将系统自带的标题栏隐藏掉
  • MainActivity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActionBar actionbar = getSupportActionBar();
        if (actionbar != null) {
            actionbar.hide();
        }
    }
}

这里我们调用了getSupportActionBar()方法来获得ActionBar的实例,然后在调用ActionBar的hide()方法将标题栏隐藏起来

1.2 自定义LinearLayout控件

  • 最终效果
    这里写图片描述

  • 实例布局
    这里写图片描述
    新增了一个TitleLayout

include确实解决了重复编写布局代码的问题,但是如果布局中有一些控件要求能够响应事件,我们还是需要再每个Activity中为这些控件单独编写一次事件注册的代码,比如说标题中的返回按钮,其实不管是在哪一个Activity中,这个按钮的功能都是相同的,即销毁当前Activity,如果在每一个活动中都需要重新注册一遍返回按钮的点击事件,无疑会增加很多重复代码,这种情况最好使用自定义控件的方式解决

  • 新建TitleLayout继承自LinearLayout
public class TitleLayout extends LinearLayout {

    public TitleLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.title, this); 
     }   
}

首先我们重写了LinearLayout中带有两个参数的构造函数,在布局中引入TitleLayout控件就会调用这个构造函数,然后在构造函数中需要对标题栏布局进行动态加载,这就要借助LayoutInflater来实现了,通过LayoutInflater的from()方法可以构造出一个LayoutInflater对象,然后调用inflate()方法就可以动态加载一个布局文件,inflate()方法接收两个参宿,第一个参数是要加载的布局文件的id,这里我们传入R.layout.title,第二个参数是给加载好的布局再添加一个父布局,这里我们想要指定为TitleLayout,于是直接传入this

  • 自定义控件创建好了,然后需要再布局文件中添加这个自定义控件
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.uicustomviews.TitleLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

添加自定义控件和添加普通控件的方法基本是一样的,只不过在添加自定义控件的时候,我们需要指明控件的完整类名,包名在这里是不可以省略的

重新运行程序,效果和使用include的效果一样
这里写图片描述

  • 下面我们尝试为标题栏中的按钮注册点击事件
  • TitleLayout
public class TitleLayout extends LinearLayout {

    public TitleLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.title, this);
        // 新增
        Button titleBack = (Button) findViewById(R.id.title_back);
        Button titleEdit = (Button) findViewById(R.id.title_edit);
        titleBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                ((Activity) getContext()).finish();
            }
        });
        titleEdit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "You clicked Edit button",
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
}

首先还是通过findViewById()方法得到按钮的实例,然后分别调用setOnClickListener()方法给两个按钮注册了点击事件,当点击返回按钮时销毁掉当前的活动,当点击编辑按钮时弹出一段文本

这样的话每当我们再一个布局中引入TitleLayout时,返回按钮和编辑按钮的点击事件就已经自动实现好了

转载请注明出处amoscxy的博客:https://mp.csdn.net/mdeditor/80151114

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页