安卓自定义控件RecyclerView

RecyclerView是安卓5.0版本对列表视图控件ListView的升级,也是属于MD设计的一部分,其功能十分强大,但是使用起来相比ListView比较复杂。

布局文件

在xml布局文件中添加RecyclerView控件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_message_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/view" />
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>

JAVA文件中使用控件的步骤

定义适配器:

使用自定义的适配器,继承了RecyclerView.Adapter,并给出封装的Holder类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class MessageAdapter extends RecyclerView.Adapter<MessageViewHolder> {
//上下文引入
private Context context;
//保存对象的信息列表
private List<MessageBeanClass> dataList;
//用于进行点击事件的监听器
private MyItemClickListener mItemClickListener;
private MyItemLongClickListener mItemLongClickListener;
//构造函数,传递上下文和数据列表
public MessageAdapter(Context c, List<MessageBeanClass> d) {
context = c;
dataList = d;
}
//创建Holder
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MessageViewHolder messageViewHolder = (MessageViewHolder) parent.getTag();
if(messageViewHolder == null) {
messageViewHolder = new MessageViewHolder(LayoutInflater.
from(context).inflate(R.layout.activity_tab_message_item,parent,false),
mItemClickListener,mItemLongClickListener);
}
return messageViewHolder;
}
//对每个列表中的选项进行设置
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
holder.name.setText(dataList.get(position).getName());
holder.message.setText(dataList.get(position).getMessageText());
holder.time.setText(dataList.get(position).getTime());
}
//返回列表的长度用于显示列表中的选项数目
@Override
public int getItemCount() {
return dataList.size();
}
//监听器设置
public void setOnItemClickListener(MyItemClickListener listener){
this.mItemClickListener = listener;
}
public void setOnItemLongClickListener(MyItemLongClickListener listener){
this.mItemLongClickListener = listener;
}
}

定义ViewHolder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//自定义的Holder,继承RecyclerView.ViewHolder,引用点击事件接口
public class MessageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnLongClickListener
{
//事件监听器
private MyItemClickListener mListener;
private MyItemLongClickListener mLongListener;
public TextView name, message,time;
public MessageViewHolder(View itemView,MyItemClickListener
listener,MyItemLongClickListener longListener) {
super(itemView);
this.mListener = listener;
this.mLongListener = longListener;
initView();
}

private void initView() {
time = (TextView) itemView.findViewById(R.id.tv_time);
name = (TextView) itemView.findViewById(R.id.tv_user_name);
message = (TextView) itemView.findViewById(R.id.tv_user_message);
itemView.setBackgroundResource(R.drawable.recycler_view_background);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
@Override
public void onClick(View view) {
if(mListener != null) {
mListener.onItemClick(view,getAdapterPosition());
}
}
@Override
public boolean onLongClick(View view) {
if(mLongListener != null) {
mLongListener.onItemLongClick(view,getAdapterPosition());
}
return true;
}
}

在Activity或Fragment中使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class MessageFragment extends Fragment implements MyItemClickListener, 
MyItemLongClickListener{
/**
* 测试数据
*/
private String[] nameTest = {"TOM","BOB","JAME"};
private String[] messageTest = {"FUCK YOU","YOU GET OUT","ONE NIGHT"};
private String[] timeTest = {"2小时前","昨天","2016-12-31"};
private RecyclerView recyclerView;
private View messageView;
private MessageAdapter adapter;
private MessageBeanClass messageBean;
private List<MessageBeanClass> messageList = new ArrayList<>();

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
messageView = inflater.inflate(R.layout.activity_tab_message, container,false);
initView();
initData();
return messageView;
}

private void initData() {
messageList.clear();
for(int i = 0; i < 3 ; i++) {
//Bitmap bitmap = BitmapFactory.decodeResource(getResources(),imageTest[i]);
String name = nameTest[i];
String message = messageTest[i];
String time = timeTest[i];
messageBean = new MessageBeanClass(name,message,time,0);
messageList.add(messageBean);
}
adapter = new MessageAdapter(getContext(),messageList);
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(this);
adapter.setOnItemLongClickListener(this);
}

private void initView() {
recyclerView = (RecyclerView) messageView.findViewById(R.id.rv_message_list);
//设置RecyclerView的布局管理器,如果是网格类型可以选择GridLayoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
//给视图选项添加分割线
recyclerView.addItemDecoration(newDividerItemDecoration(getContext(),
DividerItemDecoration.VERTICAL_LIST));
}

@Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
}

@Override
public void onItemClick(View view, int postion) {
MessageBeanClass messageBeanClass = messageList.get(postion);
if(messageBeanClass != null) {
Intent intent = new Intent();
intent.setClass(getContext(), ChattingActivity.class);
startActivity(intent);
}
}

@Override
public void onItemLongClick(View view, int postion) {
MessageBeanClass messageBeanClass = messageList.get(postion);
if(messageBeanClass != null) {
Toast.makeText(getContext(),"onItemLongClick"postion,Toast.LENGTH_SHORT).show();
}
}
}

点击事件的接口:

1
2
3
4
5
6
7
public interface MyItemClickListener {
public void onItemClick(View view, int postion);
}

public interface MyItemLongClickListener {
public void onItemLongClick(View view, int postion);
}

于是这样就完成了对RecyclerView的使用,由于在上述例子中使用了分割线,但是因为绘制分割线的代码较长,而且对该实例中可以不使用,于是就省略代码,避免篇幅太长了。

安卓数据请求方式

Post请求

  • 安卓要通过向服务器请求需要加入权限
1
uses-permission android:name="android.permission.INTERNET"/>
  • 由于网络请求是一个耗时的操作,所以我们要开启一个子线程,在子线程中我们需要传递一个url地址,url地址通过字符串传递再封装到URL对象里面
1
URL httpUrl = new URL(url);
  • 创建一个HttpURLConnection对象
1
HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();
  • 设置请求方式为post(也可以进行get方式)
1
connection.setRequestMethod("POST");
  • 设置是否可以进行流操作
1
connection.setDoOutput(true);
  • 设置请求时间不超过5s
1
connection.setReadTimeout(5000);
  • 开启一个输出流,并获得向链接的服务器进行输入数据操作
1
OutputStream out = connection.getOutputStream();
  • 向服务器提交数据的格式(post请求方式)
1
String content = "phone=" + user.getPhone() + "&username=" + user.getUsernanme() + "&password=" + user.getPassword();
  • 提交数据
1
out.write(content.getBytes());
  • 获取服务器返回的数据:

    • 开启读取服务器的带缓冲的读取器
1
BufferedReader reader = new BufferedReader(new InputStream(connect.getInputStream()));
  • 创建一个字符串缓冲器:
1
2
StringBuffer stringBuffer = new StringBuffer();
String str;
  • 当读取到的字符串不为空时就追加到缓冲器中
1
2
3
4
While((str = reader.readline()) != null) {
stringBuffer.append(str);
}
Log.d("info",stringBuffer.toString());

于是这样就可以跟服务器进行Post数据的交互了

Get请求

  • url的参数是
1
url = url + "?phone=" + user.getPhone() + "&password=" + user.getPassword();
  • 通过url的路由进行数据的请求,这是get的请求方式,但是如果进行大量的数据传输则不考虑使用get的方式

  • 网络请求是一个耗时的操作,所以我们要开启一个子线程,在子线程中我们需要传递一个url地址,url地址通过字符串传递再封装到URL对象里面

1
URL httpUrl = new URL(url);
  • 创建一个HttpURLConnection对象
1
HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();
  • 设置请求的方式为get:
1
2
3
4
5
6
7
8
9
10
11
connection.setRequestMethod("GET");
connection.setReadTimeout(5000);

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStr
eam)));
String str;
StringBuffer stringBuffer = new StringBuffer();
while((str = reader.readLine()) != null) {
stringBuffer.append(str);
}
Log.d("info",stringBuffer.toString());