GreenDao的簡單使用說明(三)多表的操作1:n
來自: http://blog.csdn.net//chenguang79/article/details/50460718
我們在使用數據庫的時候,大多數都會是多表聯合操作,不會只有一個表的,下面我們就來說一下,多表的操作,這里先拿1:n來說。這是我們平時在設計數據庫時最常用的模式。下面我來看一下,GreenDao對1:n的模式是怎么處理的。
一,我們先要新建兩個表,用來實現1:n。我們先來修改MyDaoGenerator.java這個文件。代碼如下:
package pl.surecase.eu; import de.greenrobot.daogenerator.DaoGenerator; import de.greenrobot.daogenerator.Entity; import de.greenrobot.daogenerator.Property; import de.greenrobot.daogenerator.Schema; import de.greenrobot.daogenerator.ToMany; public class MyDaoGenerator { public static void main(String args[]) throws Exception { Schema schema = new Schema(3, "greendao"); schema.setDefaultJavaPackageDao("com.guangda.dao"); Entity userBean = schema.addEntity("Users"); userBean.setTableName("Users"); //userBean.addLongProperty("id").primaryKey().index().autoincrement(); userBean.addIdProperty(); userBean.addStringProperty("uSex"); userBean.addStringProperty("uTelphone"); userBean.addStringProperty("uAge"); userBean.addStringProperty("uName"); //上面是我們用于單表操作的時建立的表 //下面是我們要建的兩個新表,一個上信息類別,一個是信自,它們的關系是1:n. //對于信息類別表,沒有什么好說的,和上面一樣,直接建立一個表就完了,我們主要來看一下信息表中,如何設置外鍵 Entity infoTypeBean = schema.addEntity("infoType"); //此處是用來實現序列化的接口 infoTypeBean.implementsSerializable(); infoTypeBean.addIdProperty(); infoTypeBean.addStringProperty("infoName"); //信息表進行建立 Entity infoBean = schema.addEntity("infos"); infoBean.implementsSerializable(); infoBean.addIdProperty(); infoBean.addStringProperty("infoTitle"); infoBean.addStringProperty("infoAuthor"); infoBean.addStringProperty("infoContent"); //這里我們為信息表,添加一個typeId外鍵,它就是infoType表的id Property typeId = infoBean.addLongProperty("typeId").getProperty(); //這里是重點,我們為這兩個表建立1:n的關系,并設置關聯字段。 infoBean.addToOne(infoTypeBean, typeId); ToMany addToMany = infoTypeBean.addToMany(infoBean,typeId); addToMany.setName("infoes"); new DaoGenerator().generateAll(schema, args[0]); } }我在代碼中加了比較詳細的注解,相信大家一看就明白了。
注意:
Schema schema = new Schema(3, "greendao");這里的版本號,你要比之前的版本號大1,原來咱們是1,我這里是3,是因為我當時寫代碼的時候,寫錯了一個地方,沒法子,就又升了一次。哈哈。。。。。。。。
二,修改我們封裝的DaoMaster.OpenHelper代碼,讓他進行升級,代碼如下
package com.example.cg.greendaolearn; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import com.guangda.dao.DaoMaster; import com.guangda.dao.infoTypeDao; import com.guangda.dao.infosDao; /** * 封裝DaoMaster.OpenHelper方法, 在更新的時候,用來保存原來的數據 * greenDao默認在更新的時候,會新建表,原來的數據就丟失了 * Created by cg on 2015/12/28. */ public class THDevOpenHelper extends DaoMaster.OpenHelper { public THDevOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) { super(context, name, factory); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { switch (oldVersion) { case 2: //創建新表,注意createTable()是靜態方法 infosDao.createTable(db, true); infoTypeDao.createTable(db,true); // 加入新字段 // db.execSQL("ALTER TABLE 'moments' ADD 'audio_path' TEXT;"); // TODO break; } } }
這里我們修改就是onUpgrade方法,在這里添加了創建新表的方法,在這里我多說一句,就是GreenDao在修改原表的時候,它會把原表刪除,這樣就會有一個問題,你原有的數據會丟,這樣,我們就要在這里處理一下,把原表數據存入臨時表中,然后再刪除,最后把數據再導回來。
三,生成建表,我們運行代碼,來看一下生成后的效果
這里有時候,我們在運行MyDaoGenerator.java代碼,生成類的時候,會提示GKB代碼無法運行,這是因為你在這個文件里寫了中文,它不認,就算是你把這個文件轉成了utf-8,也會報這個錯,這時候,我們只能用記事本打開這個文件,然后覆蓋保存,在保存時,編碼選擇 ANSI。就ok了,下面我們看一下,生成的文件列表
這樣,我們的新建的兩個表的bean和操作dao文件都已經生成好了。我們就可以進行后面的,增,刪,改,查工作了。
四, 查看生成的bean文件
我們來看一下這里生成的infos.java和infoType.java兩個文件有什么特別之后。我們先來看一下infoType.java代碼,處了代碼被序列化外,我們發現里面多了一些方法,這里主要說一下與1:N關聯有關的方法
public List<infos> getInfoes() { if (infoes == null) { if (daoSession == null) { throw new DaoException("Entity is detached from DAO context"); } infosDao targetDao = daoSession.getInfosDao(); List<infos> infoesNew = targetDao._queryInfoType_Infoes(id); synchronized (this) { if(infoes == null) { infoes = infoesNew; } } } return infoes; }
這個方法,一看名字就知道,這是得到信息列表的,也就是說,我們在得到一個信息分類的同時,只要點一下這個方法,你就可以同時得到此分類下所有的信息,這對于信息量比較少的操作來說,是相當方便的方法。但是對于大數據量來說,就沒有什么意義了。因為List這個分頁處理不行,你可能會說,我直接修改它的代碼不就完了嗎,這個可行,可是GreenDao給出的說明是這個類,最好不要進行修改。
它里面其它的方法,update,delete個人感覺沒什么意義,我一直開始以為,它會產生聯動的效果,就是刪除這個分類的時候,子信息也會被刪除,可是卻沒有發生。
我們再來看一下infos.java里面的代碼
public void setInfoType(infoType infoType) { synchronized (this) { this.infoType = infoType; typeId = infoType == null ? null : infoType.getId(); infoType__resolvedKey = typeId; } }
這個個人感覺相當使用,就是我們在得到條信息的時候,可以同時取得它的分類信息。這個在顯示詳細信息的時候相當有用啊。
下面我寫的一些代碼片斷,就是兩個頁,一個顯示信息分類,點擊信息分類,顯示此分類下所有的信息。信息分類和信息的添加,依然采用,toolbar的menu,修改與刪除功能,是長按listView。下面我把代碼放出來:
1, DbService.java添加對兩個新類的操作方法
package com.example.cg.greendaolearn.db; import android.content.Context; import android.text.TextUtils; import android.util.Log; import com.guangda.dao.DaoSession; import com.guangda.dao.UsersDao; import com.guangda.dao.infoTypeDao; import com.guangda.dao.infosDao; import java.util.List; import greendao.Users; import greendao.infoType; import greendao.infos; /** * 用戶操作類 * Created by cg on 2015/12/29. */ public class DbService { private static final String TAG = DbService.class.getSimpleName(); private static DbService instance; private static Context appContext; private DaoSession mDaoSession; private UsersDao userDao; private infosDao infoDao; private infoTypeDao typeDao; private DbService() { } /** * 采用單例模式 * @param context 上下文 * @return dbservice */ public static DbService getInstance(Context context) { if (instance == null) { instance = new DbService(); if (appContext == null){ appContext = context.getApplicationContext(); } instance.mDaoSession = BaseApplication.getDaoSession(context); instance.userDao = instance.mDaoSession.getUsersDao(); instance.infoDao = instance.mDaoSession.getInfosDao(); instance.typeDao = instance.mDaoSession.getInfoTypeDao(); } return instance; } /** * 根據用戶id,取出用戶信息 * @param id 用戶id * @return 用戶信息 */ public Users loadNote(long id) { if(!TextUtils.isEmpty(id + "")) { return userDao.load(id); } return null; } /** * 取出所有數據 * @return 所有數據信息 */ public List<Users> loadAllNote(){ return userDao.loadAll(); } /** * 生成按id倒排序的列表 * @return 倒排數據 */ public List<Users> loadAllNoteByOrder() { return userDao.queryBuilder().orderDesc(UsersDao.Properties.Id).list(); } /** * 根據查詢條件,返回數據列表 * @param where 條件 * @param params 參數 * @return 數據列表 */ public List<Users> queryNote(String where, String... params){ return userDao.queryRaw(where, params); } /** * 根據用戶信息,插件或修改信息 * @param user 用戶信息 * @return 插件或修改的用戶id */ public long saveNote(Users user){ return userDao.insertOrReplace(user); } /** * 批量插入或修改用戶信息 * @param list 用戶信息列表 */ public void saveNoteLists(final List<Users> list){ if(list == null || list.isEmpty()){ return; } userDao.getSession().runInTx(new Runnable() { @Override public void run() { for(int i=0; i<list.size(); i++){ Users user = list.get(i); userDao.insertOrReplace(user); } } }); } /** * 刪除所有數據 */ public void deleteAllNote(){ userDao.deleteAll(); } /** * 根據id,刪除數據 * @param id 用戶id */ public void deleteNote(long id){ userDao.deleteByKey(id); Log.i(TAG, "delete"); } /** * 根據用戶類,刪除信息 * @param user 用戶信息類 */ public void deleteNote(Users user){ userDao.delete(user); } /**********************信息類別*********************************/ /** * 添加或修改信息類別 * @param iType 信息類別 * @return 返回修改信息的id或是新增的信息id */ public Long SaveInfoType(infoType iType) { return typeDao.insertOrReplace(iType); } /** * 根據類別id,刪除信息類別 * @param id 信息id */ public void deleteInfoType(long id) { typeDao.load(id).delete(); } /** * 按id倒排序,來顯示所信息類別 * @return 信息類別列表 */ public List<infoType> getAllInfoTypeList() { return typeDao.queryBuilder().orderDesc(infoTypeDao.Properties.Id).list(); } /** * 根據類別id,取出類別信息 * @param id * @return */ public infoType getInfoType(long id) { return typeDao.load(id); } /**********************信息列表*********************************/ /** * 根據信息類別id,取出其類別下所有的信息 * @param typeid 類別id * @return 信息列表 */ public List<infos> getInfosByTypeId(long typeid) { return typeDao.load(typeid).getInfoes(); } /** * 添加或修改 * @param info 信息 * @return 添加或修改的id */ public long saveInfo(infos info) { return infoDao.insertOrReplace(info); } /** * 返回所有新聞,用于測試類別刪除的同步性 * @return 返回所有新聞 */ public List<infos> getAllInfos() { return infoDao.loadAll(); } /** * 分頁顯示信息 * @param typeid 信息類別 * @param pageNum 當前頁數 * @param pageSize 每頁顯示數 * @return 信息列表 */ public List<infos> getInfosBypageSize(long typeid,int pageNum,int pageSize) { return infoDao.queryBuilder().where(infosDao.Properties.TypeId.eq(typeid)).offset(pageNum-1).limit(pageSize).list(); } }
2, 分類信息頁面布局代碼:
activity_two_table.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.cg.greendaolearn.twoTableActivity" android:orientation="vertical" android:background="@color/cornflowerblue"> <include layout="@layout/toolbar" /> <ListView android:id="@+id/lv_twoTable" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout>
3, 分類信息頁面中listView的item布局:
activity_twotable_lv_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/txt_twotable_item_typeName" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:textColor="@color/greenyellow"/> </LinearLayout>
4,信息列表的Adapter代碼:
twotable_type_adpter.java
package com.example.cg.greendaolearn.adpater; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.example.cg.greendaolearn.R; import java.util.List; import greendao.infoType; /** * 兩表間,1:n中主表信息列表的adapter * Created by cg on 2016/1/4. */ public class twotable_type_adpter extends BaseAdapter { private List<infoType> list_type; private LayoutInflater inflater; public twotable_type_adpter(Context context,List<infoType> list_type) { this.inflater = LayoutInflater.from(context); this.list_type = list_type; } @Override public int getCount() { return list_type.size(); } @Override public Object getItem(int position) { return list_type.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { twoTableType tType; if(convertView==null) { tType = new twoTableType(); convertView = inflater.inflate(R.layout.activity_twotable_lv_item,null); tType.typeName = (TextView)convertView.findViewById(R.id.txt_twotable_item_typeName); convertView.setTag(tType); }else { tType = (twoTableType)convertView.getTag(); } tType.typeName.setText(list_type.get(position).getInfoName()); return convertView; } class twoTableType { TextView typeName; } }
5, 信息列表程序代碼:
twoTableActivity.java
package com.example.cg.greendaolearn; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; import com.example.cg.greendaolearn.adpater.twotable_type_adpter; import com.example.cg.greendaolearn.db.DbService; import java.util.ArrayList; import java.util.List; import greendao.infoType; public class twoTableActivity extends AppCompatActivity implements twoTableDialogTypeFragment.addInfoTypeOnClickListener,twoTableDialogTypeItemFragment.txtClickListener { private Toolbar toolbar; //定義toolbar private ListView lv_twoTable; private List<infoType> list_type; private twotable_type_adpter tAdapter; private DbService db; private twoTableDialogTypeFragment twoDialogType; private twoTableDialogTypeItemFragment twoDialogTypeItem; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_two_table); toolbar = (Toolbar)this.findViewById(R.id.toolbar); toolbar.setTitle("多表操作"); // 標題的文字需在setSupportActionBar之前,不然會無效 setSupportActionBar(toolbar); db = DbService.getInstance(this); initControls(); initData(); } /** * 初始化控件 */ private void initControls() { lv_twoTable = (ListView)findViewById(R.id.lv_twoTable); lv_twoTable.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent dIntent = new Intent(); dIntent.setClass(twoTableActivity.this,twoTableDetailActivity.class); dIntent.putExtra("typeId", list_type.get(position).getId()); dIntent.putExtra("typeName", list_type.get(position).getInfoName()); startActivity(dIntent); } }); /** * 長按事件 */ lv_twoTable.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { twoDialogTypeItem = new twoTableDialogTypeItemFragment(list_type.get(position).getId(),position); twoDialogTypeItem.show(getFragmentManager(),"item"); return true; } }); } private void initData() { list_type = new ArrayList<>(); list_type = db.getAllInfoTypeList(); tAdapter = new twotable_type_adpter(this,list_type); lv_twoTable.setAdapter(tAdapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_two_table, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.menu_twoTable_typeAdd) { twoDialogType = new twoTableDialogTypeFragment(0,"",0); twoDialogType.show(getFragmentManager(),"add"); return true; } return super.onOptionsItemSelected(item); } @Override public void OnaddInfoTypeOnClickListener(String typeName, long typeId,int postion) { infoType iType = new infoType(); iType.setInfoName(typeName); if(typeId!=0) { iType.setId(typeId); } if(db.SaveInfoType(iType) < 1) { Toast.makeText(this, "數據修改失敗!", Toast.LENGTH_SHORT).show(); } if(typeId!=0) { list_type.remove(postion); } list_type.add(postion,iType); tAdapter.notifyDataSetChanged(); twoDialogType.dismiss(); } @Override public void OntxtClickListener(int flag,long typeId,int postion) { //0:刪除 1:修改 if(flag==0) { db.deleteInfoType(typeId); list_type.remove(postion); tAdapter.notifyDataSetChanged(); Toast.makeText(this,"刪除成功!",Toast.LENGTH_SHORT).show(); }else { twoDialogType = new twoTableDialogTypeFragment(list_type.get(postion).getId(),list_type.get(postion).getInfoName(),postion); twoDialogType.show(getFragmentManager(),"edit"); } twoDialogTypeItem.dismiss(); } }
6,點擊add按鈕彈出框布局:
fragment_onetable_dialog.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="新聞類別:" android:textColor="@color/black" android:padding="5dp"/> <EditText android:id="@+id/edit_twotable_typeName" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:textColor="@color/black"/> </LinearLayout>
7,點擊add按鈕彈出框代碼:
twoTableDialogTypeFragment.java
package com.example.cg.greendaolearn; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.content.DialogInterface; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; /** * 兩表操作,1:n 新聞類別添加彈出框 * Created by cg on 2016/1/4. */ public class twoTableDialogTypeFragment extends DialogFragment { private String typeName; private long typeId; private int postion; private String btnText; public twoTableDialogTypeFragment(long typeId,String typeName,int postion) { this.typeId = typeId; this.typeName = typeName; this.postion = postion; } public interface addInfoTypeOnClickListener { void OnaddInfoTypeOnClickListener(String typeName,long typeId,int postion); } private EditText edit_twotable_typeName; @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // Get the layout inflater LayoutInflater inflater = getActivity().getLayoutInflater(); View view = inflater.inflate(R.layout.fragment_twotable_typedialog, null); edit_twotable_typeName = (EditText)view.findViewById(R.id.edit_twotable_typeName); edit_twotable_typeName.setText(typeName); if(typeId!=0) { btnText = "修改"; }else { btnText = "添加"; } builder.setView(view) .setTitle("添加新聞類別") .setPositiveButton(btnText, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { addInfoTypeOnClickListener addtype = (addInfoTypeOnClickListener)getActivity(); addtype.OnaddInfoTypeOnClickListener(edit_twotable_typeName.getText().toString(),typeId,postion); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { edit_twotable_typeName.setText(""); } }); return builder.show(); } }
8,長按item彈出操作框布局:
fragment_twotable_typeitemdialog.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/txt_twotable_typeitem_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="編輯" android:textSize="18sp" android:gravity="center" android:padding="15dp"/> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/gray"/> <TextView android:id="@+id/txt_twotable_typeitem_delete" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="刪除" android:textSize="18sp" android:gravity="center" android:padding="15dp"/> </LinearLayout>
9,長按item彈出操作框代碼:
twoTableDialogTypeItemFragment.java
package com.example.cg.greendaolearn; import android.app.DialogFragment; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.TextView; /** * 兩表操作 1:n,長按彈出修改與刪除按鈕 * Created by cg on 2016/1/4. */ public class twoTableDialogTypeItemFragment extends DialogFragment { public interface txtClickListener { void OntxtClickListener(int flag,long typeId,int postion); } private long typeId; private int postion; public twoTableDialogTypeItemFragment(long typeId,int postion) { this.typeId = typeId; this.postion = postion; } private TextView txt_twotable_typeitem_edit; private TextView txt_twotable_typeitem_delete; @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); txt_twotable_typeitem_edit = (TextView)view.findViewById(R.id.txt_twotable_typeitem_edit); txt_twotable_typeitem_edit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { txtClickListener txtClick = (txtClickListener)getActivity(); txtClick.OntxtClickListener(1,typeId,postion); } }); txt_twotable_typeitem_delete = (TextView)view.findViewById(R.id.txt_twotable_typeitem_delete); txt_twotable_typeitem_delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { txtClickListener txtClick = (txtClickListener)getActivity(); txtClick.OntxtClickListener(0,typeId,postion); } }); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE); View view = inflater.inflate(R.layout.fragment_twotable_typeitemdialog,container); return view; } }
10,子頁,信息列表布局:
activity_two_table_detail.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.cg.greendaolearn.twoTableDetailActivity" android:orientation="vertical"> <include layout="@layout/toolbar" /> <ListView android:id="@+id/lv_twoTable_detail" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout>
11,子頁,listview中item的布局:
activty_twotable_detail_lv_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/txt_twotable_detail_item_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:textColor="@color/black"/> <TextView android:id="@+id/txt_twotable_detail_item_author" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:textColor="@color/black" android:gravity="right"/> <TextView android:id="@+id/txt_twotable_detail_item_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:textColor="@color/black"/> </LinearLayout>
12, 子頁,Adatper代碼:
twotable_info_adpter.java
package com.example.cg.greendaolearn.adpater; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.example.cg.greendaolearn.R; import java.util.List; import greendao.infos; /** * 兩表操作 1:n 子表的列表Adapter * Created by cg on 2016/1/4. */ public class twotable_info_adpter extends BaseAdapter { private List<infos> list_info; private LayoutInflater inflater; public twotable_info_adpter(Context context,List<infos> list_info) { this.inflater = LayoutInflater.from(context); this.list_info = list_info; } @Override public int getCount() { return list_info.size(); } @Override public Object getItem(int position) { return list_info.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { infoDetail iDetail; if(convertView==null) { iDetail = new infoDetail(); convertView = inflater.inflate(R.layout.activty_twotable_detail_lv_item,null); iDetail.title = (TextView)convertView.findViewById(R.id.txt_twotable_detail_item_title); iDetail.author = (TextView)convertView.findViewById(R.id.txt_twotable_detail_item_author); iDetail.content = (TextView)convertView.findViewById(R.id.txt_twotable_detail_item_content); convertView.setTag(iDetail); }else { iDetail = (infoDetail)convertView.getTag(); } iDetail.title.setText(list_info.get(position).getInfoTitle()); iDetail.author.setText(list_info.get(position).getInfoType().getInfoName() + "-" + list_info.get(position).getInfoAuthor()); iDetail.content.setText(list_info.get(position).getInfoContent()); return convertView; } class infoDetail { TextView title; TextView author; TextView content; } }
13, 子頁,代碼:
twoTableDetailActivity.java
package com.example.cg.greendaolearn; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.widget.ListView; import com.example.cg.greendaolearn.adpater.twotable_info_adpter; import com.example.cg.greendaolearn.db.DbService; import java.util.ArrayList; import java.util.List; import greendao.infos; public class twoTableDetailActivity extends AppCompatActivity implements twoTableDetailDailogFragment.addDetailClickListener { private Toolbar toolbar; //定義toolbar private ListView lv_twoTable_detail; private List<infos> list_info; private twotable_info_adpter iAdapter; public long typeId; public String typeName; private DbService db; private twoTableDetailDailogFragment detail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_two_table_detail); typeId = getIntent().getLongExtra("typeId",0); typeName = getIntent().getStringExtra("typeName"); toolbar = (Toolbar)this.findViewById(R.id.toolbar); toolbar.setTitle(typeName); // 標題的文字需在setSupportActionBar之前,不然會無效 setSupportActionBar(toolbar); db = DbService.getInstance(this); initControls(); initData(); } /** * 初始化數據 */ private void initData() { list_info = new ArrayList<>(); list_info = db.getInfosByTypeId(typeId); iAdapter = new twotable_info_adpter(this,list_info); lv_twoTable_detail.setAdapter(iAdapter); } /** * 初始化控件 */ private void initControls() { lv_twoTable_detail = (ListView)findViewById(R.id.lv_twoTable_detail); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_two_table_detail, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.menu_twoTable_detailAddAdd) { detail = new twoTableDetailDailogFragment("","","",0,0); detail.show(getFragmentManager(),"add"); return true; } return super.onOptionsItemSelected(item); } @Override public void OnaddDetailClickListener(String title, String author, String content, long infoId, int postion) { infos info = new infos(); info.setInfoAuthor(author); info.setInfoTitle(title); info.setInfoContent(content); info.setTypeId(typeId); db.saveInfo(info); detail.dismiss(); list_info.add(0,info); iAdapter.notifyDataSetChanged(); } }
14, 子頁,添加信息布局:
fragment_twotable_typedetaildialog.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="標題:" android:gravity="center" android:padding="5dp"/> <EditText android:id="@+id/edit_detail_title" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:textColor="@color/black"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="作者:" android:gravity="center" android:padding="5dp"/> <EditText android:id="@+id/edit_detail_author" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:textColor="@color/black"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="內容:" android:gravity="center" android:padding="5dp"/> <EditText android:id="@+id/edit_detail_content" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:lines="3" android:gravity="top|left" android:textColor="@color/black"/> </LinearLayout> </LinearLayout>
15,子頁,添加代碼
oneTableItemDialogFragment.java
package com.example.cg.greendaolearn; import android.app.DialogFragment; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.TextView; /** * Created by cg on 2015/12/30. */ public class oneTableItemDialogFragment extends DialogFragment { private long id; //用戶id private int postion; //list中的編號 private TextView txt_onetable_update; private TextView txt_onetable_delete; public interface EditUserOnClickListener { //flag標識,0表示刪除,1表示修改 void onEditUserOnClick(long id,int postion,int flag); } public oneTableItemDialogFragment(long id,int postion) { this.id = id; this.postion = postion; } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE); View view = inflater.inflate(R.layout.fragment_onetable_itemdialog,container); return view; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); txt_onetable_update = (TextView)view.findViewById(R.id.txt_onetable_update); txt_onetable_update.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { EditUserOnClickListener listener = (EditUserOnClickListener) getActivity(); listener.onEditUserOnClick(id,postion,1); } }); txt_onetable_delete = (TextView)view.findViewById(R.id.txt_onetable_delete); txt_onetable_delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { EditUserOnClickListener listener = (EditUserOnClickListener) getActivity(); listener.onEditUserOnClick(id,postion,0); } }); } }