CriminalIntent项目的强大完善

CriminalIntentAPP的又一次革命

经过了前面五章代码的编写与结构的梳理,这款app的界面已基本成型。接下来,我会对后面三章的内容进行分析,帮助同学们进一步地完善相关的功能,相信你们一定会喜欢后续的改变的。

第十二章:日期对话框,fragment数据传递

1、使用 DialogFragment

AppCompat兼容库能通过支持库的方式将部分最新系统的特色功能移植到Android旧版本系统中。

所以要在 Porject Structure 中添加 appcompat-v7 的依赖!

2、创建 DialogFragment

建议将 AlertDialog 封装在 DialogFragment (Fragment的子类)实例中使用;

通过使用 FragmentManager 管理对话框,可以更灵活地显示对话框。

 

 首先需要一个针对 dialog 的布局文件,如 DatePicker 作为根元素的 Dialog 用于选择日期。

<?xml version="1.0" encoding="utf-8"?>
 <DatePicker 
xmlns:android="http://schemas.android.com/apk/res/android"     
android:id="@+id/dialog_date_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:calendarViewShown="false"> </DatePicker>

然后新建一个父类是 DialogFragment 的类 DatePickerFragment,重写其中的 onCreateDialog 方法,返回一个AlertDialog

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    // 使用 LayoutInflater 引用布局文件创建用于显示 Dialog 的 View
    View v = LayoutInflater.from(getActivity())
                .inflate(R.layout.dialog_date, null);

    return new AlertDialog.Builder(getActivity())
        .setView(v) // 设置视图
        .setTitle(R.string.date_picker_title) //设置标题
        // 设置 OK 按钮,OnClickListener 暂时留空
        .setPositiveButton(android.R.string.ok, null)
        // 使用 Builder 的 create() 方法创建 Dialog 并返回
        .create(); 
}

 

在使用 DialogFragment 时,使用成员方法 show 来显示 dialog:

// 在 Fragment 中为 DatePickerFragment 添加一个 Tag
private static final String DIALOG_DATE = "DialogDate";
……
// 在 Fragment 内部获取 FragmentManager
FragmentManager manager = getFragmentManager(); 
DatePickerFragment dialog = new DatePickerFragment();
// 显示对话框
dialog.show(manager, DIALOG_DATE);

 

3将数据传递到对话框

需要在 DatePickerFragment 中建立获取实例的 newInstance 方法,其中需要的参数是传递的信息即可,示例如下

// DatePickerFragment.java

public static DatePickerFragment newInstance(Date date) {
    // 新建一个 Bundle 对象用于存放数据
    Bundle args = new Bundle();
    args.putSerializable(ARG_DATE, date);
    DatePickerFragment fragment = new DatePickerFragment();
    // 使用 fragment arguments 来传递参数
    fragment.setArguments(args);
    return fragment;
}

 

4、从对话框回传数据

设置目标 fragment,传递数据给目标 Fragment

处理由同一 activity 托管的两个 fragment 间的数据返回时,可借用Fragment.onActivityResult(...)方法。因此,直接调用目标 fragment 的Fragment.onActivityResult(...)方法,,就能实现数据的回传。

 

// DatePickerFragment.java

public static final String EXTRA_DATE =
    "com.kniost.criminalintent.date";
 ……                
private void sendResult(int resultCode, Date date) {
    // 防止出错
    if (getTargetFragment() == null) {
        return; 
    }
    Intent intent = new Intent();
    // 放置数据到 Intent 中
    intent.putExtra(EXTRA_DATE, date);
    // 获取目标 fragment,调用其 onActivityResult 方法,其中 RequestCode 是用 getTargetRequestCode 方法获取的,resultCode 是传入参数,intent 包含了数据
    getTargetFragment()
        .onActivityResult(getTargetRequestCode(), resultCode, intent);
}

// CrimeFragment.java

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // 如果一切正常,调用 sendResult 的方法时传入的参数应该就是 Activity.RESULT_OK,所以不会直接 return
    if (resultCode != Activity.RESULT_OK) {
        return;
    }

    // 如此判断方便有多个回传时使用
    if (requestCode == REQUEST_DATE) {
        Date date = (Date) data
            .getSerializableExtra(DatePickerFragment.EXTRA_DATE);
        mCrime.setDate(date); mDateButton.setText(mCrime.getDate().toString());
    }
}

 

 第十三章:工具栏,菜单,层级式导航

1、在 XML 文件中定义菜单

<?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto">
        <item
            android:id="@+id/menu_item_new_crime"
            android:icon="@android:drawable/ic_menu_add"
            android:title="@string/new_crime"
            app:showAsAction="ifRoom|withText"/>
</menu>

 

 2、实例化菜单

在CrimeListFragment.java中,覆盖onCreateOptionsMenu(Menu, MenuInflater)方法,实例化fragment_crime_list.xml中定义的菜单,如下:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.fragment_crime_list, menu);
}

 

3、让菜单发挥作用

 

在初始化菜单后,我们已经能在应用界面上看到菜单了,现在需要让菜单能够有实际的作用,比如新增一个 Crime,要达到这个目的,我们需要做下面几件事:

 

  1. 在 Model 层增加一个新增的函数
  2. 在 Controller 层增加菜单监听

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
       switch (item.getItemId()) {
       case R.id.menu_item_new_crime:
            Crime crime = new Crime();
          CrimeLab.get(getActivity()).addCrime(crime);
          Intent intent = CrimePagerActivity
                  .newIntent(getActivity(), crime.getId());
          startActivity(intent);
          return true;
       default:
            super.onOptionsItemSelected(item);
      }
    }

 第十四章:SQLite数据库的使用

基本框架:

其中基本步骤:

定义 CrimeTable 内部类数据、表字段(CrimeDbSchema.java)

 

package edu.niit.software.criminalintent.database;

/**
 * Created by 666 on 2017/9/29.
 */

public class CrimeDbSchema {
    public static final class CrimeTable{
        public static final String NAME = "crimes";

        public static final class Cols{
            public static final String UUID = "uuid";
            public static final String TITLE = "title";
            public static final String DATE = "date";
            public static final String SOLVED = "solved";
        }
    }
}

 

 

 

 

 

 

创建 CrimeBaseHelper 类(CrimeBaseHelper.java)

 

package edu.niit.software.criminalintent.database;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import edu.niit.software.criminalintent.database.CrimeDbSchema.CrimeTable;


/**
 * Created by 666 on 2017/9/29.
 */

public class CrimeBaseHelper extends SQLiteOpenHelper {
    private static final int VERSION = 1;
    private static final String DATABASE_NAME = "crimeBase.db";

    public CrimeBaseHelper(Context context){
        super(context , DATABASE_NAME , null , VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        db.execSQL("create table " + CrimeTable.NAME + "(" + "_id integer primary key autoincrement ," +
                CrimeTable.Cols.UUID + "," +
                CrimeTable.Cols.TITLE + "," +
                CrimeTable.Cols.DATE + "," +
                CrimeTable.Cols.SOLVED + ")"
        );
    }

    @Override
    public void onUpgrade(SQLiteDatabase db , int oldVersion , int newVersion){

    }
}

 

通过这些代码与逻辑的整理,这款App的界面功能还能更强大哦

是不是很靓眼,最后祝大家在代码编写的途中都可以持之以恒,未来很美好,要努力哦!

 

posted @ 2017-10-15 20:20  陨落星辰xs  阅读(213)  评论(0编辑  收藏  举报