GreenDao的简单使用说明(三)多表的操作1:n

起浮沉落 9年前

来自: 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);              }          });      }  }