转载请注明出处amoscxy的博客:https://mp.youkuaiyun.com/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.youkuaiyun.com/mdeditor/80151114