Android実験5---通信録(ListViewリフレッシュ問題の解決といくつかの符号化規範のまとめ)
じっけんようきゅう
SQliteに基づいて、ListViewは通信録を実現し、UIを設計すると同時に以下の機能を実現する:1)ユーザーの名前、電話を入力する;2)名前でユーザー情報を検索する;3)全てのユーザー情報を表示する;4)指定されたユーザーの情報を削除することを実現する;4)指定されたユーザーの情報を更新することを実現する;
ListViewリフレッシュについて
本実験で使用したアダプタはBaseAdapterであり,最初はアダプタでList変数タイプを定義するのではなく,グローバル変数resultsを直接宣言し,データの削除・変更を行った.
その結果、データをリフレッシュすることはできない、解決策は、アダプタに変数を宣言し、アダプタを呼び出す方法:notifyDataSetChanged()である、これにより、アダプタの変数が変化すると、この方法が呼び出され、リフレッシュ操作が行う.
コード仕様のまとめ境界問題 ListViewをリフレッシュできると、最後のデータを削除するとlistViewが表示する境界問題が発生します.クリアリストに問題があることを発見した:以前私はデータを検索した時にリストのクリアを行ったが、最後のデータを削除した後、データテーブルが空になったが、このデータはクリアされず、リストViewに残った.修正:データを検索ときは、まずクリア操作を行い、その後、データを検索し、空またはListと判断する.add(). 条件判断 次のコードの最初のif文の中で、私はデータがない时、データがないことを提示して、それからなくなって...データがある情况で、それからデータがある情况に専念します.
修正:
returnの前に、いくつかのデータ操作ストリームを閉じることを忘れないでください.また、初期値nullについても、cursorがnullである、cursorは存在しないと判断する.close()!
idでデータを削除し、データを更新する
ListViewをクリックしてsqliteに対応する行のidを取得します.positionはlistviewレイアウトの位置であることを知っています.positionを使用して、私たちが望んでいるidを取得することができます.listviewをクリックして、次の関数を呼び出します.
私の表の設計は、
Idはすでにグローバル変数として使用されており、後のdelete関数とupdate関数で使用しやすい.
レイアウトの更新
前述ListViewのリフレッシュ:Adapterによる方法notifyDataSetChanged():
UIレイアウト設計
main.xml
List_Item.xml
ソースコード
Info.java
SQliteに基づいて、ListViewは通信録を実現し、UIを設計すると同時に以下の機能を実現する:1)ユーザーの名前、電話を入力する;2)名前でユーザー情報を検索する;3)全てのユーザー情報を表示する;4)指定されたユーザーの情報を削除することを実現する;4)指定されたユーザーの情報を更新することを実現する;
ListViewリフレッシュについて
本実験で使用したアダプタはBaseAdapterであり,最初はアダプタでList変数タイプを定義するのではなく,グローバル変数resultsを直接宣言し,データの削除・変更を行った.
class MyBaseAdapter extends BaseAdapter{
private List<Info> results;// Adapter , ,
@Override
public int getCount() {
return results.size();
}
// Item
@Override
public Object getItem(int position) {
return results.get(position);
}
// Item id
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// ListView Item
View view = View.inflate(MainActivity.this, R.layout.list_item, null);
TextView textView = view.findViewById(R.id.item);
textView.setText("name : "+ results.get(position).getName() + " tel : "+ results.get(position).getTel());
return view;
}
}
その結果、データをリフレッシュすることはできない、解決策は、アダプタに変数を宣言し、アダプタを呼び出す方法:notifyDataSetChanged()である、これにより、アダプタの変数が変化すると、この方法が呼び出され、リフレッシュ操作が行う.
コード仕様のまとめ
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = null ;
if( cursor == null || cursor.getCount() == 0 ){ //
Toast.makeText(this," ",Toast.LENGTH_SHORT).show();
}else{
cursor.moveToFirst();
Info info = new Info();
// newList.clear();// , ---- , ,
//baseAdapter.results.clear();
info.setName(cursor.getString(1));
info.setTel(cursor.getString(2));
newList.add(info);
}
while (cursor.moveToNext()){
newList.add(new Info(cursor.getString(1),cursor.getString(2)));
}
baseAdapter.results = newList; //
baseAdapter.notifyDataSetChanged();//
cursor.close();
db.close();
修正:
if( cursor == null || cursor.getCount() == 0 ){ //
Toast.makeText(this," ",Toast.LENGTH_SHORT).show();
if(cursor!=null) cursor.close();
db.close();
return;
}
returnの前に、いくつかのデータ操作ストリームを閉じることを忘れないでください.また、初期値nullについても、cursorがnullである、cursorは存在しないと判断する.close()!
idでデータを削除し、データを更新する
ListViewをクリックしてsqliteに対応する行のidを取得します.positionはlistviewレイアウトの位置であることを知っています.positionを使用して、私たちが望んでいるidを取得することができます.listviewをクリックして、次の関数を呼び出します.
resultList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Info info = baseAdapter.results.get(position);
nameText.setText(info.getName());
telText.setText(info.getTel());
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.query("information",null,null,null,null,null,null);
cursor.moveToPosition(position);
Id = cursor.getString(0); // Item id
//
cursor.close();
db.close();
}
});
私の表の設計は、
db.execSQL("CREATE table information(id INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20),tel VARCHAR(20))");
cursorが最初の列を取得した値はcursor.getString(0)
です.Idはすでにグローバル変数として使用されており、後のdelete関数とupdate関数で使用しやすい.
public int update(String name,String tel){
if(Id == null || Id.length()==0){
Toast.makeText(this," , !",Toast.LENGTH_SHORT).show();
return 0;
}
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name",name);
contentValues.put("tel",tel);
int number = db.update("information",contentValues,"id=?",new String[]{Id}); // id
db.close();
updateUI(); //
return number;
}
public int delete(){
if(Id == null || Id.length()==0){
Toast.makeText(this," , !",Toast.LENGTH_SHORT).show();
return 0;
}
SQLiteDatabase db = helper.getWritableDatabase();
int num = db.delete("information","id = ? ",new String[]{Id});
db.close();
updateUI();//
return num;
}
レイアウトの更新
前述ListViewのリフレッシュ:Adapterによる方法notifyDataSetChanged():
baseAdapter.notifyDataSetChanged();//
であるが、これだけでは終わらない.Adapterデータが変化しなければならないことを前提として、この方法が機能しない.データを削除/更新した後、notifyDataSetChanged()をそのまま使用するとリフレッシュできません.list
は変更されていないので、「クエリーデータ、クエリーの結果をlistに追加するとlistデータが変化し、notifyDataSetChangedを呼び出すと機能します」:public void updateUI(){
nameText.setText("");
telText.setText("");
Id="";
search("",""); // , ,
baseAdapter.notifyDataSetChanged();//
}
UIレイアウト設計
main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="20dp"
android:paddingBottom="20dp"
android:paddingRight="20dp"
android:paddingTop="20dp"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/L1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:background="#ffffff">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" :"
android:textSize="30sp" />
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/name"
android:maxLines="1"
android:hint=" " />
LinearLayout>
<LinearLayout
android:id="@+id/L2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/L1"
android:background="#ffffff"
android:layout_marginTop="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" :"
android:textSize="30sp"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/tel"
android:maxLines="1"
android:hint=" "
/>
LinearLayout>
<LinearLayout
android:id="@+id/L3"
android:layout_below="@+id/L2"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/add_b"
android:text=" "
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/search_b"
android:text=" "/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/delete_b"
android:text=" "/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/update_b"
android:text=" "/>
LinearLayout>
<ListView
android:id="@+id/result_list"
android:layout_below="@id/L3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
ListView>
RelativeLayout>
List_Item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item"
android:text=" list_item"
android:textSize="30sp"/>
LinearLayout>
ソースコード
package jzt.com.shiyan5;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private EditText nameText;
private EditText telText;
private ListView resultList;
private Button search_b;
private Button delete_b;
private Button update_b;
private Button add_b;
private String Id ="";
MyHelper helper;
MyBaseAdapter baseAdapter;
private List<Info> newList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// SQLite
helper = new MyHelper(this);
init();
}
public void init(){
nameText = findViewById(R.id.name);
telText = findViewById(R.id.tel);
//
resultList = findViewById(R.id.result_list);
// Adapter
baseAdapter = new MyBaseAdapter();
baseAdapter.results = new ArrayList<>();
// Adapter
resultList.setAdapter(baseAdapter);
search_b = findViewById(R.id.search_b);
delete_b = findViewById(R.id.delete_b);
update_b = findViewById(R.id.update_b);
add_b = findViewById(R.id.add_b);
search_b.setOnClickListener(this);
delete_b.setOnClickListener(this);
update_b.setOnClickListener(this);
add_b.setOnClickListener(this);
newList = new ArrayList<>();
resultList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Info info = baseAdapter.results.get(position);
nameText.setText(info.getName());
telText.setText(info.getTel());
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.query("information",null,null,null,null,null,null);
cursor.moveToPosition(position);
Id = cursor.getString(0); // Item id
//
cursor.close();
db.close();
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.add_b:
insert(nameText.getText().toString().trim(),telText.getText().toString().trim());
break;
case R.id.search_b:
search(nameText.getText().toString().trim(),telText.getText().toString().trim());
break;
case R.id.delete_b:
int num1 = delete();
if (num1 == 1){
Toast.makeText(this," ",Toast.LENGTH_SHORT).show();
}else if(num1 == 0){
Toast.makeText(this," ",Toast.LENGTH_SHORT).show();
}
break;
case R.id.update_b:
int num = update(nameText.getText().toString().trim(),telText.getText().toString().trim());
if(num==0 || num==-1){
Toast.makeText(this," ",Toast.LENGTH_SHORT).show();
}else if(num==1){
Toast.makeText(this," ",Toast.LENGTH_SHORT).show();
}
break;
}
}
public void updateUI(){
nameText.setText("");
telText.setText("");
Id="";
search("",""); // , ,
baseAdapter.notifyDataSetChanged();//
}
public int update(String name,String tel){
if(Id == null || Id.length()==0){
Toast.makeText(this," , !",Toast.LENGTH_SHORT).show();
return 0;
}
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name",name);
contentValues.put("tel",tel);
int number = db.update("information",contentValues,"id=?",new String[]{Id}); // id
db.close();
updateUI(); //
return number;
}
public void insert(String name,String tel){
if(name.trim().length()==0||tel.trim().length()==0){
Toast.makeText(this," !",Toast.LENGTH_SHORT).show();
return;
}
name = name.trim();
tel = tel.trim();
SQLiteDatabase writableDatabase = helper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name",name);
contentValues.put("tel",tel);
// , null, contentvalues
writableDatabase.insert("information",null,contentValues);
Toast.makeText(this," ",Toast.LENGTH_SHORT).show();
updateUI();//
writableDatabase.close();
}
public int delete(){
if(Id == null || Id.length()==0){
Toast.makeText(this," , !",Toast.LENGTH_SHORT).show();
return 0;
}
SQLiteDatabase db = helper.getWritableDatabase();
int num = db.delete("information","id = ? ",new String[]{Id});
db.close();
updateUI();//
return num;
}
//
public void search(String name,String tel){
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = null ;
//
newList.clear();
baseAdapter.results.clear();
name = name.trim();
tel = tel.trim();
if(name.length()==0 && tel.length()==0){
cursor = db.query("information",null,null,null,null,null,null);
}else if(name.length()!=0 && tel.length()==0){
cursor = db.query("information", null, "name=?", new String[]{name }, null, null, null);
}else if(name.length()==0&&tel.length()!=0){
cursor = db.query("information",null,"tel=?",new String[]{tel},null,null,null);
}else if(name.length()!=0 && tel.length()!=0){
cursor = db.query("information",null,"name=? and tel=?",new String[]{name , tel},null,null,null);
}else if(name.length()==0 && tel.length() ==0){
cursor = db.query("information",null,null,null,null,null,null) ;
}
if( cursor == null || cursor.getCount() == 0 ){ //
Toast.makeText(this," ",Toast.LENGTH_SHORT).show();
if(cursor!=null) cursor.close();
db.close();
return;
}else{
cursor.moveToFirst();
Info info = new Info();
// newList.clear();// , ---- , ,
//baseAdapter.results.clear();
info.setName(cursor.getString(1));
info.setTel(cursor.getString(2));
newList.add(info);
}
while (cursor.moveToNext()){
newList.add(new Info(cursor.getString(1),cursor.getString(2)));
}
baseAdapter.results = newList; //
baseAdapter.notifyDataSetChanged();//
Toast.makeText(this," "+newList.size()+" ",Toast.LENGTH_SHORT).show();
cursor.close();
db.close();
}
class MyBaseAdapter extends BaseAdapter{
private List<Info> results;// Adapter , ,
@Override
public int getCount() {
return results.size();
}
// Item
@Override
public Object getItem(int position) {
return results.get(position);
}
// Item id
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// ListView Item
View view = View.inflate(MainActivity.this, R.layout.list_item, null);
TextView textView = view.findViewById(R.id.item);
textView.setText("name : "+ results.get(position).getName() + " tel : "+ results.get(position).getTel());
return view;
}
}
}
Info.java
package jzt.com.shiyan5;
public class Info {
private String name;
private String tel;
public Info(){
}
public Info(String name,String tel){
this.name = name;
this.tel = tel;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
}