Android入门(5)| 高级控件
在前面我们学习了Android中的最基本的控件,接下来我们来一起学习几个更加高级的控件吧。
![](https://img.haomeiwen.com/i12070003/28f16c1b0bbe9d06.png)
1.ListView 滚动控件
控件ListView的主要功能就是将一些我们需要展示的信息通过滚动的方式来展出,用户只需要用手指在APP上滚动即可看到不同的信息。在一般的APP当中都会有这样的功能。
同样先创建项目,然后在布局上添加LiseView控件:
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
接着我们修改主活动的代码:
package com.example.yzbkaka.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] data = {"1","2","3","4","5","6","7","8","9","10"}; //先定义一个字符串数组充当信息
ListView listView = (ListView)findViewById(R.id.list_view);
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(MainActivity.this
,android.R.layout.simple_list_item_1,data); //为data定义一个适配器
listView.setAdapter(myAdapter); //启动适配器
}
}
我们先在这里新建了一个String类型的数组,接着是使用适配器来将数组中的内容传到LIstView中,创建适配器时的构造函数需要传入三个参数,第一个是Context,这里就传入MainActivity就可以,第二个是要传入子项布局的id,这里我们使用AS中默认的即可,最后一个参数就是我们要传入的数据了。最后我们使用setAdapter()的方法来启动适配器即可。
ListView中的点击事件所使用的方法也是和其他的控件不太一样,它主要使用的是setItemClickListener()的方法来进行,修改主代码:
package com.example.yzbkaka.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String[] data = {"1","2","3","4","5","6","7","8","9","10"};
ListView listView = (ListView)findViewById(R.id.list_view);
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(MainActivity.this
,android.R.layout.simple_list_item_1,data);
listView.setAdapter(myAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { //设置监听
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(MainActivity.this, "you click it", Toast.LENGTH_SHORT).show(); //具体操作
}
});
}
}
这里就是使用的setOnItemClickListener()的方法来为ListView设置了一个监听,每当我们点击LIstView中任何一个时就会回调onItemClick()方法,之后我们就可以在它里面来设定具体的操作了。
2.RecyclerView 更强大的滚动控件
RecyclerView是相对于ListView更加强大和方便的滚动控件,RecyclerView不仅能够实现上下滚动的功能,还能够实现左右滚动、瀑布模式等等更加美观的展现方式。
同样还是创建一个空项目。由于RecyclerView不是Android内置的控件,因此我们需要在库中添加依赖,打开app—build.gradle,找到dependencies
的闭包,在里面添加一行依赖:
implementation 'com.android.support:recyclerview-v7:27.1.1'
接着我们在布局里面将RecyclerView添加进去:
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
之后我们就在主代码中将数据传输到RecyclerView中:
package com.example.yzbkaka.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ArrayList<String> myList = new ArrayList<>(); //新建立的测试信息list
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
RecyclerAdapter adapter = new RecyclerAdapter(this,myList); //创建适配器
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); //创建排列的方式
recyclerView.setLayoutManager(linearLayoutManager); //设置排列的方式
recyclerView.setAdapter(adapter); //启动适配器
}
}
使用RecyclerView同样需要适配器,我们这里使用的是自己建立的RecyclerAdapter,接着是创建布局排列方式的LinearLayoutManager对象,然后使用setLayoutManager()的方法来将布局加载进去,最后是启动适配器。
下面我们来创建RecyclerAdapter,新建类,然后添加代码:
package com.example.yzbkaka.myapplication;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyHolder> {
Context context;
ArrayList<String> list;
public RecyclerAdapter(Context context,ArrayList<String> list){
this.context = context;
this.list = list;
}
public class MyHolder extends RecyclerView.ViewHolder{
TextView textView;
public MyHolder(View itemView){
super(itemView);
textView = (TextView)itemView.findViewById(R.id.text_view);
}
}
@Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_main,parent,false
);
MyHolder myHolder = new MyHolder(view);
return myHolder;
}
@Override
public void onBindViewHolder(MyHolder holder, int position) {
String str = list.get(position);
holder.textView.setText(str);
}
@Override
public int getItemCount() {
return list.size();
}
}
之后运行我们就可以实现和ListView一样的效果了。当然,RecyclerView之所以强大,不仅仅是可以实现ListView,还能够做到ListView所不能实现的效果,我们修改主代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
RecyclerAdapter adapter = new RecyclerAdapter(this,myList);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); //添加这一行
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
}
}
可以看到我们在这添加了一行linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
,它的含义就是让RecyclerView中的内容呈水平排列来展现出来。
3.创建自定义控件
我们先来看一下控件的布局的继承结构图:
![](https://img.haomeiwen.com/i12070003/cbe7426e2732a066.png)
可以看到我们所用的控件都是直接或者间接继承自View的,而所有的布局都是继承自ViewGroup的。View是一种最基本的Android控件,它能够在屏幕上的划定一块区域并且能够响应这块区域的各种事件,所以我们使用的各种控件其实就是在View的基础之上又添加各自的功能;ViewGroup也是同样的道理。知道了这些,我们就可以利用他们的原理来自己创建控件。
这里我们创建一个APP里面的任务栏控件,它包括返回、显示信息和退出的功能。还是先创建一个空项目,然后新建一个布局,添加控件:
<Button
android:id="@+id/button_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:text="Back" />
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:layout_margin="5dp"
android:text="Title Text"/>
<Button
android:id="@+id/button_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:text="Exit" />
在这里我们是创建了2个按钮和1个标题栏,它们的排列方式就是水平排列,这里出现的新的控件属性android:layout_margin
的含义是指定控件在上下左右方向上偏移的距离,这里我们制定为5dp就好。
由于我们设定的布局是一个任务栏,所以在每一个活动的布局当中它都应该出现,但是如果在每一个活动的布局中都写一遍这样的代码未免效率低下,因此,我们可以将任务栏的布局直接用一行代码添加进去,在主活动的布局中添加:
<include layout="@layout/title"/>
仅仅使用这一行代码,我们就可以将任务栏的布局添加进去,之后的所有活动的布局我们都可以这样来添加。
最后就是要将系统自带的任务栏给去除掉,我们在主活动中添加代码:
package com.example.yzbkaka.myuiapplication;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar(); //先获得ActionBar对象
if(actionBar != null){ //如果actionBar不是空的
actionBar.hide(); //将actionBar隐藏
}
}
}
在这里我们使用的是getSupportActionBar()的方法来得到ActionBar对象,然后使用if来判断,如果不为空,则使用hide的方法来隐藏。
之后我们就需要对任务栏的控件来添加具体的操作活动了,同样,如果我们在每一个活动中都写上具体操作的代码是很浪费时间的。所以在这里我们就可以将任务栏变为一个控件,而这个控件就需要我们来自己创造了。新建一个TitleLayout:
package com.example.yzbkaka.myuiapplication;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class TitleLayout extends LinearLayout {
public TitleLayout(final Context context, AttributeSet attributeSet){
super(context,attributeSet);
LayoutInflater.from(context).inflate( R.layout.title,this);
Button back = (Button)findViewById(R.id.button_1);
TextView title = (TextView)findViewById(R.id.text_view);
Button exit = (Button)findViewById(R.id.button_2);
back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(),"you click back",Toast.LENGTH_LONG).show();
}
});
exit.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(), "you click exit", Toast.LENGTH_SHORT).show();
}
});
}
}
TitleLayout继承自LinearLayout,而它的构造函数需要传入2个参数。接着是使用LayoutInflater的from()方法来创建一个LayoutInflater的对象,最后对该对象使用inflate()方法来加载这个布局文件,inflate()方法需要的两个参数分别是需要加载的布局和为该布局添加的父布局,在这里具体就是指title这个布局以及TitleLayout。之后就是为这里面的控件来添加操作了。
最后我们就可以将这个自定义控件放到布局里面:
<com.example.yzbkaka.myuiapplication.TitleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"></com.example.yzbkaka.myuiapplication.TitleLayout>
就这样,我们就创造了一个我们自己的任务栏控件。