本次实验是在上次的基础之上进行了新视图和控件的学习,上一次的传送门:传送门
目录
一、实验目的
1、掌握UI设计中的layout布局(约束布局)与基本控件(button、text、imageview等)
2、掌握复杂控件与adapter的使用(请使用RecycleView进行设计)。在主界面中的某个tab页里添加列表项。
二、实验内容
1、功能简介
本次主要新增的功能是:
1、将通讯录页面内容设置为recycleView,从而可以实现列表功能,并且recycleView的每个item有两个元素,分别为imageView和textView用于放置照片和设置文字。
2、为recycleView中的每个item设置了点击监听事件, 当点击item时,会进行activity的跳转,直观的看就是打开了个人资料页面,通过传参数跳转的方式可以看到个人资料页面的名字和微信号。
3、数据库连接,通过配置数据库连接类和实体类以及接口层,实现了能够从数据库中查询返回数据,其中recyleView中的item的text来源于返回数据。
2、核心代码
(1)Adapter
用于recyleView的初始化和设置每个item的值与监听。
package com.example.homework;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class Adapter extends RecyclerView.Adapter<Adapter.myViewHolder> {
private ArrayList<String> mydata;
private Context mycontext;
private View inflater;
private ArrayList<Drawable> myimage;
public Adapter(ArrayList<String> data,Context context,ArrayList<Drawable> image) {
this.mydata=data;
this.mycontext=context;
this.myimage=image;
}
@Override
public myViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
inflater=LayoutInflater.from(mycontext).inflate(R.layout.item,viewGroup,false);
myViewHolder holder=new myViewHolder(inflater);
return holder;
}
@Override
public void onBindViewHolder(myViewHolder holder, @SuppressLint("RecyclerView") int position) {
holder.textView.setText(mydata.get(position));
holder.imageView.setImageDrawable(myimage.get(position));
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(mycontext,contact_info.class);
intent.putExtra("name",mydata.get(position));
mycontext.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mydata.size();
}
public class myViewHolder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView;
public myViewHolder(View itemView) {
super(itemView);
textView=itemView.findViewById(R.id.textView4);
imageView=itemView.findViewById(R.id.imageView2);
}
}
}
(2)contentFragment
用于接受数据和对通讯录页面上的组件进行操控。
package com.example.homework;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.homework.mysql.Dao;
import com.example.homework.mysql.Model;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class ContactFragment extends Fragment{
private RecyclerView recyclerView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view;
view=inflater.inflate(R.layout.contact_page,container,false);
recyclerView=view.findViewById(R.id.recycleView);
ArrayList<Drawable> images=new ArrayList<>();
final ArrayList<String> data=new ArrayList<>();
Thread ListInit = new Thread(() -> {
List<Model> list = Dao.getList();
for(int i=0;i<list.size();i++){
data.add(String.valueOf(list.get(i)));
}
for(int i=0;i<data.size();i++){
Drawable drawable= ContextCompat.getDrawable(getContext(), R.drawable.pig);
images.add(drawable);
};
});
ListInit.start();
Context context=getContext();
Adapter adapter=new Adapter(data,context,images);
LinearLayoutManager layoutManager=new LinearLayoutManager(context);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
return view;
}
}
(3)数据库操作配置
package com.example.homework.mysql;
import android.util.Log;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBUtil {
private static String diver = "com.mysql.jdbc.Driver";
private static String url =characterEncoding=utf-8";
private static String user = "name";//用户名
private static String passw¥¥d = "";//密码
/*
* 连接数据库
* */
public static Connection getConn() {
Connection conn = null;
try {
Class.forName(diver);
conn = (Connection) DriverManager.getConnection(url, user, password);//获取连接
Log.e("getConn", "连接成功");
} catch (ClassNotFoundException e) {
Log.e("getConn", e.getMessage(), e);
e.printStackTrace();
} catch (SQLException e) {
Log.e("getConn", e.getMessage(), e);
e.printStackTrace();
}
return conn;
}
public static void close(Statement state, Connection conn) {
if (state != null) {
try {
state.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(ResultSet rs, Statement state, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (state != null) {
try {
state.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
3、设计流程简介
在上次的基础之上,首先需要新建控件recycleView,以及新建一个layout item.xml用于给列表中的每个元素赋值。然后需要新建一个Adapter类用于对recycleView的初始化和控制,其中包括设置image和data,获取position等等一系列函数。然后需要在reycleView所绑定的主函数中进行值的接收与设置,此时运行项目则可以看到实现了列表的功能。
然后我创建了数据库操作的几个配置文件,通过配置数据库的基本参数以及需要的数据的实体类,还有相应的sql语句和接收的数据,在测试完能够成功收到数据之后,在主函数中调用函数即可获取值。现在看到的就是从数据库中查询数据而来的列表。
接下来为了能够实现每个item的资料页面,又需要在layout中新增一个xml然后进行组件的配置。完成之后回到Adapter中为每个item新增点击监听事件,并且事件中通过startActivity的方式切换页面,并且完成传值,此处传的内容为name。
到此为止整个设计就结束了。
4、问题解决
(1)数据库报错
在配置完数据库之后,进行测试发现总是报错
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
我在经过排查发现配置信息没有问题,实体类的配置也没有问题,其中只是在函数调用的时候会出现问题。于是通过查找发现要想完成数据库连接,就需要在安卓的子线程里面去操作。代码如下:
final ArrayList<String> data=new ArrayList<>();
Thread ListInit = new Thread(() -> {
List<Model> list = Dao.getList();//数据库操作语句
for(int i=0;i<list.size();i++){
data.add(String.valueOf(list.get(i)));
}
for(int i=0;i<data.size();i++){
Drawable drawable= ContextCompat.getDrawable(getContext(), R.drawable.pig);
images.add(drawable);
};
});
ListInit.start();
(2)监听事件
为每个item设置监听事件,最开始我是想与之前一样,在父页面设置监听,然后来get点击view的id从而进行判断。但是在这样做的时候,一点击程序就崩溃了,于是只能选择在初始化recylcleView的时候进行设置监听事件。
三、源码
还没上传