今天是规定的团队开发冲刺第二阶段的最后一天,冲刺时期每日做事已在团队博客里记录,我没有更新个人博客,上周比较忙,不少学科到了期末交作业的时候,针对Android的代码学习量比较少,每日打卡也说不上什么东西,就想着最后一天做一个小总结。因为时间有限,这段时间完成的是使用ListView遍历显示存储在数据库中的用户笔记记录,点击相应item会进入笔记详细界面,显示笔记和附上的图片缩略图,点击缩略图可以查看大图,提供返回界面的按钮。目前做的这个只是一个初稿,算是实现了功能的雏形,还需要完善删除功能和界面优化等等,下面先看一下初稿的样子吧。
代码:
主页面:activity_main.xml
只有一个TextView显示大标题,和ListView组件
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:orientation="vertical" 8 tools:context=".MainActivity"> 9 10 <LinearLayout 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content" 13 android:orientation="horizontal" 14 > 15 16 <TextView 17 android:layout_width="0dp" 18 android:layout_height="wrap_content" 19 android:gravity="center_horizontal" 20 android:layout_weight="1" 21 android:hint="标题" 22 android:textSize="30sp" 23 android:textColor="#3b3b3b" 24 ></TextView> 25 26 <TextView 27 android:layout_width="0dp" 28 android:layout_height="wrap_content" 29 android:gravity="center_horizontal" 30 android:layout_weight="1" 31 android:hint="学科" 32 android:textSize="30sp" 33 android:textColor="#3b3b3b" 34 ></TextView> 35 </LinearLayout> 36 <View 37 android:layout_width="match_parent" 38 android:layout_height="2px" 39 android:background="#3b3b3b"></View> 40 <ListView 41 android:id="@+id/list_view" 42 android:layout_width="match_parent" 43 android:layout_height="match_parent" 44 android:scrollbars="none" 45 android:divider="#CCCCCC" 46 android:dividerHeight="2px" 47 ></ListView> 48 49 </LinearLayout>
笔记页面:activity_note_view.xml
根据传过来的信息去服务器端拿到图片和文件数据,这里固定设置一个ImageView和一个TextView,用来查看实现效果,最终实现的样式需要ImageView动态添加。
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:orientation="vertical" 8 tools:context=".MainActivity"> 9 10 <ImageView 11 android:id="@+id/trypng" 12 android:layout_width="120dp" 13 android:layout_height="120dp" 14 ></ImageView> 15 16 <TextView 17 android:id="@+id/trytxt" 18 android:layout_width="match_parent" 19 android:layout_height="240dp" 20 android:hint="读取文件内容" 21 app:layout_constraintBottom_toBottomOf="parent" 22 app:layout_constraintLeft_toLeftOf="parent" 23 app:layout_constraintRight_toRightOf="parent" 24 app:layout_constraintTop_toTopOf="parent" /> 25 26 <Button 27 android:id="@+id/exit" 28 android:layout_width="wrap_content" 29 android:layout_height="wrap_content" 30 android:text="返回" 31 ></Button> 32 33 </LinearLayout>
查看大图页面:dialog_photo.xml
这里在点击缩略图后实现查看大图的功能。
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content"> 5 6 <ImageView 7 android:id="@+id/large_image" 8 android:layout_width="match_parent" 9 android:layout_height="700dp" 10 android:layout_centerHorizontal="true" 11 android:layout_centerVertical="true"></ImageView> 12 13 </LinearLayout>
list设置:list_view.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="horizontal"> 6 <TextView 7 android:id="@+id/li_title" 8 android:layout_width="0dp" 9 android:layout_height="wrap_content" 10 android:gravity="center_horizontal" 11 android:layout_marginTop="10sp" 12 android:layout_marginBottom="10sp" 13 android:layout_weight="1" 14 android:hint="标题" 15 android:textSize="20sp" 16 android:textColor="#3b3b3b" 17 ></TextView> 18 19 <TextView 20 android:id="@+id/li_kemu" 21 android:layout_width="0dp" 22 android:layout_height="wrap_content" 23 android:gravity="center_horizontal" 24 android:layout_marginTop="10sp" 25 android:layout_marginBottom="10sp" 26 android:layout_weight="1" 27 android:hint="学科" 28 android:textSize="20sp" 29 android:textColor="#3b3b3b" 30 ></TextView> 31 32 </LinearLayout>
java后台代码:
MainActivity.java:这里实现ListView显示,点击事件等,连接的是本地的servlet。
1 package com.example.toas; 2 3 import androidx.appcompat.app.AlertDialog; 4 import androidx.appcompat.app.AppCompatActivity; 5 6 import android.content.Intent; 7 import android.os.Bundle; 8 import android.os.Handler; 9 import android.os.Message; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.view.ViewGroup; 13 import android.widget.AdapterView; 14 import android.widget.Button; 15 import android.widget.ListView; 16 import android.widget.TextView; 17 18 import org.json.JSONArray; 19 import org.json.JSONObject; 20 21 import java.io.BufferedReader; 22 import java.io.InputStreamReader; 23 import java.io.OutputStream; 24 import java.net.HttpURLConnection; 25 import java.net.URL; 26 import java.util.ArrayList; 27 28 public class MainActivity extends AppCompatActivity { 29 private TextView li_title,li_kemu; 30 private ListView list_view; 31 private ArrayList<MyNoteBean> listData; 32 private MyNoteAdapter adapter; 33 private Handler handler; 34 35 36 37 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 38 return inflater.inflate(R.layout.activity_main,container,false); 39 } 40 @Override 41 protected void onCreate(Bundle savedInstanceState) { 42 super.onCreate(savedInstanceState); 43 setContentView(R.layout.activity_main); 44 45 li_title = (TextView)findViewById(R.id.li_title); 46 li_kemu = (TextView)findViewById(R.id.li_kemu); 47 list_view = (ListView)findViewById(R.id.list_view); 48 listData = new ArrayList<MyNoteBean>(); 49 50 handler = new Handler(){ 51 public void handleMessage(Message msg){ 52 super.handleMessage(msg); 53 if(msg.what==1){ 54 adapter=new MyNoteAdapter(MainActivity.this,listData); 55 list_view.setAdapter(adapter); 56 adapter.notifyDataSetChanged(); 57 } 58 } 59 }; 60 final String path="http://192.168.101.18:8080/CloudNote/MyNoteServlet"; 61 //使用HttpURLConnection需要子线程 62 new Thread(new Runnable() { 63 @Override 64 public void run() { 65 //从上一个页面拿到输入的日期数据 66 HttpURLConnection conn=null; 67 try{ 68 URL url=new URL(path); 69 conn=(HttpURLConnection)url.openConnection(); 70 //设置post格式,这里格式要跟servlet里一致 71 conn.setRequestMethod("POST"); 72 //设置超时时间 73 conn.setConnectTimeout(5000); 74 conn.setReadTimeout(5000); 75 //post格式不能用缓存 76 conn.setUseCaches(false); 77 conn.setDoInput(true); 78 String data="user="+"try"; 79 //将传给servlet的数据写入传输 80 OutputStream out=conn.getOutputStream(); 81 //这里注意要更改传输数据的格式,getBytes() 82 out.write(data.getBytes()); 83 out.flush(); 84 out.close(); 85 conn.connect(); 86 87 //这里开始接收从servlet里传回来的数据 88 BufferedReader reader=new BufferedReader(new InputStreamReader(conn.getInputStream())); 89 String line=null; 90 //传回来的是一个JSONArray类型的数据,需要对其进行解析 91 if((line=reader.readLine())!=null){ 92 //开始解析 93 JSONArray jsonArray=new JSONArray(line); 94 for(int i=0;i<jsonArray.length();i++){ 95 JSONObject jsonObject=jsonArray.getJSONObject(i); 96 int id=jsonObject.getInt("id"); 97 String nianji=jsonObject.getString("nianji"); 98 String kemu=jsonObject.getString("kemu"); 99 String title=jsonObject.getString("title"); 100 String note=jsonObject.getString("note"); 101 String image1=jsonObject.getString("image1"); 102 String image2=jsonObject.getString("image2"); 103 String image3=jsonObject.getString("image3"); 104 String SEE=jsonObject.getString("SEE"); 105 106 MyNoteBean mnb = new MyNoteBean(); 107 mnb.setTitle(title); 108 mnb.setKemu(kemu); 109 mnb.setId(id); 110 mnb.setNianji(nianji); 111 mnb.setNote(note); 112 mnb.setImage1(image1); 113 mnb.setImage2(image2); 114 mnb.setImage3(image3); 115 mnb.setSEE(SEE); 116 listData.add(mnb); 117 } 118 } 119 Message msg = new Message(); 120 msg.what = 1; 121 handler.sendMessage(msg); 122 }catch(Exception e){ 123 e.printStackTrace(); 124 } 125 } 126 }).start(); 127 128 list_view.setOnItemClickListener(new AdapterView.OnItemClickListener() { 129 @Override 130 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 131 MyNoteBean MNB = listData.get(position); 132 Intent intent = new Intent(MainActivity.this,NoteView.class); 133 intent.putExtra("note",MNB.getNote()); 134 intent.putExtra("img1",MNB.getImage1()); 135 startActivity(intent); 136 } 137 }); 138 } 139 }
NoteView.java:实现笔记的读取文件和图片,显示功能,缩略图查看大图功能。
1 package com.example.toas; 2 3 import androidx.appcompat.app.AlertDialog; 4 import androidx.appcompat.app.AppCompatActivity; 5 6 import android.content.Intent; 7 import android.graphics.Bitmap; 8 import android.graphics.BitmapFactory; 9 import android.os.Bundle; 10 import android.os.Handler; 11 import android.os.Message; 12 import android.view.LayoutInflater; 13 import android.view.View; 14 import android.widget.Button; 15 import android.widget.ImageView; 16 import android.widget.TextView; 17 18 import java.io.BufferedReader; 19 import java.io.IOException; 20 import java.io.InputStream; 21 import java.io.InputStreamReader; 22 import java.net.HttpURLConnection; 23 import java.net.MalformedURLException; 24 import java.net.URL; 25 26 public class NoteView extends AppCompatActivity { 27 private TextView trytxt; 28 private Button exit; 29 private ImageView trypng; 30 private Myhandler handler1; 31 private Txthandler handler2; 32 33 class Myhandler extends Handler { 34 public void handleMessage(Message msg) { 35 trypng = (ImageView) findViewById(R.id.trypng); 36 trypng.setImageBitmap((Bitmap) msg.obj); 37 } 38 } 39 40 class Txthandler extends Handler { //文本handler 41 public void handleMessage(Message msg) { 42 trytxt = (TextView) findViewById(R.id.trytxt); 43 trytxt.setText(msg.obj.toString()); 44 } 45 } 46 47 @Override 48 protected void onCreate(Bundle savedInstanceState) { 49 super.onCreate(savedInstanceState); 50 setContentView(R.layout.activity_note_view); 51 52 exit = (Button) findViewById(R.id.exit); 53 handler1 = new Myhandler(); 54 handler2 = new Txthandler(); 55 56 Intent intentdata=getIntent(); 57 final String inote=intentdata.getStringExtra("note"); 58 final String iimg1=intentdata.getStringExtra("img1"); 59 60 new Thread(new Runnable() { 61 @Override 62 public void run() { 63 try { 64 String path = "http://39.101.190.190:8080/filesource/"+iimg1; 65 URL url = new URL(path); 66 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 67 conn.setRequestMethod("GET"); 68 conn.setConnectTimeout(8000); 69 conn.setReadTimeout(8000); 70 conn.connect(); 71 if (conn.getResponseCode() == 200) { 72 InputStream is = conn.getInputStream(); 73 Bitmap bm = BitmapFactory.decodeStream(is); 74 seeBigimg(bm); 75 Message msg = new Message(); 76 msg.obj = bm; 77 handler1.sendMessage(msg); 78 } 79 } catch (MalformedURLException e) { 80 e.printStackTrace(); 81 } catch (IOException e) { 82 e.printStackTrace(); 83 } 84 } 85 }).start(); 86 87 new Thread(new Runnable() { 88 @Override 89 public void run() { //文本读取调用 90 String txtpath = "http://39.101.190.190:8080/filesource/"+inote; 91 try { 92 URL turl = new URL(txtpath); 93 HttpURLConnection cont = (HttpURLConnection) turl.openConnection(); 94 cont.setReadTimeout(8000); 95 cont.setConnectTimeout(8000); 96 cont.connect(); 97 InputStream input = cont.getInputStream(); 98 BufferedReader in = new BufferedReader(new InputStreamReader(input)); 99 String line = null; 100 StringBuffer sb = new StringBuffer(); 101 while ((line = in.readLine()) != null) { 102 sb.append(line); 103 } 104 if (cont.getResponseCode() == 200) { 105 Message msg = new Message(); 106 msg.obj = sb; 107 handler2.sendMessage(msg); 108 } 109 } catch (MalformedURLException e) { 110 e.printStackTrace(); 111 } catch (IOException e) { 112 e.printStackTrace(); 113 } 114 } 115 }).start(); 116 117 exit.setOnClickListener(new View.OnClickListener() { 118 @Override 119 public void onClick(View v) { 120 Intent intent=new Intent(NoteView.this,MainActivity.class); 121 startActivity(intent); 122 } 123 }); 124 } 125 126 private void seeBigimg(final Bitmap bm) { 127 trypng = (ImageView) findViewById(R.id.trypng); 128 trypng.setOnClickListener(new View.OnClickListener() { 129 @Override 130 public void onClick(View paramView) { 131 LayoutInflater inflater = LayoutInflater.from(NoteView.this); 132 View imgEntryView = inflater.inflate(R.layout.dialog_photo,null); 133 final AlertDialog dialog = new AlertDialog.Builder(NoteView.this).create(); 134 ImageView img1 = (ImageView)imgEntryView.findViewById(R.id.large_image); 135 img1.setImageBitmap(bm); 136 dialog.setView(imgEntryView); 137 dialog.show(); 138 139 imgEntryView.setOnClickListener(new View.OnClickListener() { 140 @Override 141 public void onClick(View paramView) { 142 dialog.cancel(); 143 } 144 }); 145 } 146 }); 147 } 148 }
MyNoteBean.java:bean
1 package com.example.toas; 2 3 public class MyNoteBean { 4 private int Id; 5 private String User; 6 private String Nianji; 7 private String Kemu; 8 private String Title; 9 private String Note; 10 private String Image1; 11 private String Image2; 12 private String Image3; 13 private String SEE; 14 15 public int getId(){ return Id; } 16 public void setId(int id){ Id=id; } 17 public String getUser(){ return User; } 18 public void setUser(String user){ User=user; } 19 public String getNianji(){ return Nianji; } 20 public void setNianji(String nianji){ Nianji=nianji; } 21 public String getKemu(){ return Kemu; } 22 public void setKemu(String kemu){ Kemu=kemu; } 23 public String getTitle(){ 24 return Title; 25 } 26 public void setTitle(String title){ Title=title; } 27 public String getNote(){ 28 return Note; 29 } 30 public void setNote(String note){ Note=note; } 31 public String getImage1(){return Image1;}; 32 public void setImage1(String image1){Image1=image1;} 33 public String getImage2(){return Image2;} 34 public void setImage2(String image2){Image2=image2;} 35 public String getImage3(){return Image3;} 36 public void setImage3(String image3){Image3=image3;} 37 public String getSEE(){return SEE;} 38 public void setSEE(String see){SEE=see;} 39 }
MyNoteAdapter.java:适配器
1 package com.example.toas; 2 3 import android.content.Context; 4 import android.view.LayoutInflater; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.BaseAdapter; 8 import android.widget.TextView; 9 10 import java.util.ArrayList; 11 12 public class MyNoteAdapter extends BaseAdapter { 13 private Context context; 14 private ArrayList<MyNoteBean> listData; 15 16 public MyNoteAdapter(Context context,ArrayList<MyNoteBean> listData){ 17 this.context=context; 18 this.listData=listData; 19 } 20 21 @Override 22 public int getCount() { return listData.size(); } 23 24 @Override 25 public Object getItem(int position) { return listData.get(position); } 26 27 @Override 28 public long getItemId(int position) { return position; } 29 30 @Override 31 public View getView(int position, View convertView, ViewGroup parent) { 32 MyNoteBean MNB = (MyNoteBean) getItem(position); 33 ViewHolder viewHolder=null; 34 if(convertView==null){ 35 LayoutInflater inflater=LayoutInflater.from(context); 36 //这里将ListView的格式xml文件名称写入,名字千万别写错,否则调用后显示的格式会发生错误 37 convertView=inflater.inflate(R.layout.list_item,null); 38 viewHolder=new ViewHolder(); 39 viewHolder.li_title=(TextView)convertView.findViewById(R.id.li_title); 40 viewHolder.li_kemu=(TextView)convertView.findViewById(R.id.li_kemu); 41 convertView.setTag(viewHolder); 42 } 43 viewHolder=(ViewHolder)convertView.getTag(); 44 MyNoteBean model=listData.get(position); 45 viewHolder.li_title.setText(model.getTitle()); 46 viewHolder.li_kemu.setText(model.getKemu()); 47 return convertView; 48 } 49 } 50 class ViewHolder{ 51 public TextView li_title; 52 public TextView li_kemu; 53 }
效果:
最后我改动了一下之前写的记录功能的代码,以前实现的记录功能会在手机内存里生成txt文件和png文件(在特定的文件夹内)。与成员协商后决定在实现提交的同时删除这些生产文件。代码如下:
声明对象,1234分别对应txt,图片1,图片2,图片3
private String del1,del2,del3,del4;//删除文件用
使用OkHttp上传的同时给对象赋值:【del1,del2,del3,del4】
1 String noteuser = user_str+"_note"; 2 File Notefile = doString(note_str,noteuser); 3 del1 = Environment.getExternalStorageDirectory().toString()+"/CloudNoteTXT/"+Notefile.getName(); 4 builder.addFormDataPart("note",Notefile.getName(),RequestBody.create(NoteType,Notefile)); 5 6 //图片文件,设定最多上传3张,不包括+号图片。 7 int pic_i=0; 8 for(HashMap<String,Bitmap>pic:imageItem){ 9 Set<String> set=pic.keySet(); 10 for(String key:set){ 11 if(pic_i==0){ 12 //跳过默认的+号图片 13 pic_i++; 14 continue; 15 } 16 //取出bitmap,转换成file,上传 17 else if(pic_i==1){ 18 Bitmap fbm1 = pic.get(key); 19 //设置文件命名前缀部分 20 String image1user = user_str+"_image1"; 21 //调用方法生成图片文件 22 File dofile = doImage(fbm1,image1user); 23 del2 = Environment.getExternalStorageDirectory().toString()+"/CloudNoteImage/"+dofile.getName(); 24 builder.addFormDataPart("image1",dofile.getName(),RequestBody.create(PNG,dofile)); 25 pic_i++; 26 } 27 else if(pic_i==2){ 28 Bitmap fbm2 = pic.get(key); 29 //设置文件命名前缀部分 30 String image2user = user_str+"_image2"; 31 //调用方法生成图片文件 32 File dofile = doImage(fbm2,image2user); 33 del3 = Environment.getExternalStorageDirectory().toString()+"/CloudNoteImage/"+dofile.getName(); 34 builder.addFormDataPart("image2",dofile.getName(),RequestBody.create(PNG,dofile)); 35 pic_i++; 36 } 37 else if(pic_i==3){ 38 Bitmap fbm3 = pic.get(key); 39 //设置文件命名前缀部分 40 String image3user = user_str+"_image3"; 41 //调用方法生成图片文件 42 File dofile = doImage(fbm3,image3user); 43 del4 = Environment.getExternalStorageDirectory().toString()+"/CloudNoteImage/"+dofile.getName(); 44 builder.addFormDataPart("image3",dofile.getName(),RequestBody.create(PNG,dofile)); 45 pic_i++; 46 } 47 } 48 }
删除文件的方法:
1 //删除文件 2 public void deletefile(String df){ 3 File file = new File(df); 4 if(file.isFile()){ 5 file.delete(); 6 } 7 }
调用删除文件方法在OkHttp完成之后,注意要对对象进行非空判断,否则运行出错:
1 @Override 2 public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { 3 Log.i("TRYxxx","连接的消息"+response.message()); 4 if(response.isSuccessful()){ 5 Log.i("TRYxxx","连接成功"); 6 //okhttp里直接调用Toast会报错 7 handler.post(new Runnable() { 8 @Override 9 public void run() { 10 Toast.makeText(MainActivity.this, "上传成功", Toast.LENGTH_SHORT).show(); 11 } 12 }); 13 deletefile(del1); 14 if(del2!=null){ 15 deletefile(del2); 16 } 17 if(del3!=null){ 18 deletefile(del3); 19 } 20 if(del4!=null){ 21 deletefile(del4); 22 } 23 } 24 }