BNR Android Demo学习笔记(一)——CrimeIntent

时间:2022-09-15 19:15:32

开发环境:win7,Android Studio 1.2,

1、Model

Crime,数据模型,每个Crime有一个UUID作为唯一标识。

package tina.criminalintent;

import java.util.Date;
import java.util.UUID; /**
* Created by CW3479 on 2015/7/13.
*/
public class Crime {
private UUID mId;
private String mTitle;
private Date mDate;
private boolean mSolved; public Crime(){
//Genetate unique identifier
mId=UUID.randomUUID(); } public UUID getId() {
return mId;
} public String getTitle() {
return mTitle;
} public void setTitle(String title) {
mTitle = title;
} public Date getDate() {
if(mDate==null)
mDate=new Date();
return mDate;
} public void setDate(Date date) {
mDate = date;
} public boolean isSolved() {
return mSolved;
} public void setSolved(boolean solved) {
mSolved = solved;
} @Override
public String toString() {
return mTitle;
}
}

CrimeLab,数据库,用了单例模式,保证了应用运行过程中使用同一个数据库。目前还是简单应用,CrimeLab里面的数据(Crime)是初始化时设定的,只能查询和更改,以后会进行改造,对CrimeLab进行增删操作。

package tina.criminalintent;

import android.content.Context;

import java.util.ArrayList;
import java.util.UUID; /**
* Created by CW3479 on 2015/7/13.
*/
public class CrimeLab {
private ArrayList<Crime> mCrimes; private static CrimeLab sCrimeLab;
private Context mAppContext; public static CrimeLab getInstance(Context context) {
if(sCrimeLab==null) {
sCrimeLab = new CrimeLab(context.getApplicationContext());
}
return sCrimeLab;
} private CrimeLab(Context appContext) {
mAppContext=appContext;
mCrimes=new ArrayList<Crime>(); for(int i=0;i<10;i++){
Crime crime=new Crime();
crime.setTitle("Crime #"+i);
crime.setSolved(i%2==0);
mCrimes.add(crime);
}
} public ArrayList<Crime> getCrimes() {
return mCrimes;
} public Crime getCrime(UUID id){
for(Crime crime:mCrimes){
if(crime.getId().equals(id)){
return crime;
}
}
return null;
}
}

2、Controller & View

以往都是直接用Activity进行应用的设计,从这个demo开始,使用Fragment来完成应用的设计,增加应用程序的灵活性。关于Fragment,可以参考这篇文章Android Fragment 真正的完全解析(上)。需要注意的是,有关Fragment的类,有静态支持库版本和标准包版本(不知道这么说合不合适),前者是为了兼容Android3.0以下版本,需要导入Android Support库(android.support.v4.*),后者就在android.app.*包里,两者的使用方法大致相同,写程序的时候考虑是否向下兼容来做选择即可。

这个Demo按照书上,使用静态支持库。

首先,SingleFragmentActivity,可看做一个放置有FragmentContainer的Activity抽象类。其中的抽象方法createFragment可以用来实现不同的Fragment。书上的例程继承的是FragmentActivity类,但是我在用模拟器运行的时候发现没有像书中一样出现ActionBar。查了一番,原来ActionBarActivity是FragmentActivity的子类,所以我直接就继承了ActionBarActivity,这个也是Android Studio的Blank Activity模板中默认使用的Activity类。

package tina.criminalintent;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.ActionBarActivity; /**
* Created by CW3479 on 2015/7/13.
*/
public abstract class SingleFragmentActivity extends ActionBarActivity {
protected abstract Fragment createFragment(); @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment); FragmentManager fm=getSupportFragmentManager();
Fragment fragment=fm.findFragmentById(R.id.fragmentContainer);
if(fragment==null){
fragment=createFragment();
fm.beginTransaction()
.add(R.id.fragmentContainer,fragment)
.commit();
}
}
}

其对应的布局文件activity_fragment.xml如下,只有一个id为fragmentContainer的FrameLayout,FrameLayout里面不放置任何子控件。

<FrameLayout 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"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="tina.criminalintent.CrimeActivity"
android:id="@+id/fragmentContainer"> </FrameLayout>

上面有了基本的模板了,接下来就是第一个页面啦。应用一打开,就是一个列表页面,显示CrimeLab中的Crime。

CrimeListActivity继承上面的SingleFragmentActivity,创建一个CrimeListFragment,放置到fragmentContainer中。

package tina.criminalintent;

import android.support.v4.app.Fragment;

/**
* Created by CW3479 on 2015/7/13.
*/
public class CrimeListActivity extends SingleFragmentActivity { @Override
protected Fragment createFragment() {
return new CrimeListFragment();
}
}

要显示列表,CrimeListFragment继承了ListFragment,从CrimeLab单例中获取Crime数据,再根据mCrimes构建ArrayAdapter,给列表中的每一行赋予数据,然后对item点击事件做响应,跳转到相应的Detail页面。

package tina.criminalintent;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView; import java.util.ArrayList; public class CrimeListFragment extends ListFragment { private ArrayList<Crime> mCrimes; private CrimeAdapter mAdapter; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.crimes_title); mCrimes=CrimeLab.getInstance(getActivity()).getCrimes();
mAdapter=new CrimeAdapter(mCrimes);
setListAdapter(mAdapter);
} @Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Crime crime=((CrimeAdapter)getListAdapter()).getItem(position); // Intent intent=new Intent(getActivity(),CrimeActivity.class);
Intent intent=new Intent(getActivity(),CrimePagerActivity.class);
intent.putExtra(CrimeFragment.EXTRA_CRIME_ID, crime.getId());
startActivity(intent);
} private class CrimeAdapter extends ArrayAdapter<Crime>{
public CrimeAdapter(ArrayList<Crime> crimes) {
super(getActivity(), 0, crimes);
} @Override
public View getView(int position, View convertView, ViewGroup parent) { if(convertView==null){
convertView=getActivity().getLayoutInflater()
.inflate(R.layout.list_item_crime,null);
} Crime c=getItem(position);
TextView titleTextView=(TextView)convertView.findViewById(R.id.crime_list_item_title);
titleTextView.setText(c.getTitle()); TextView dateTextView=(TextView)convertView.findViewById(R.id.crime_list_item_date);
dateTextView.setText(c.getDate().toString()); CheckBox solvedCheckBox=(CheckBox)convertView.findViewById(R.id.crime_list_item_solvedCheckBox);
solvedCheckBox.setChecked(c.isSolved()); return convertView;
}
} @Override
public void onResume() {
super.onResume();
((CrimeAdapter)getListAdapter()).notifyDataSetChanged();
}
}

上面的列表对应的item布局文件list_item_crime.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/crime_list_item_title"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/crime_list_item_date"
android:layout_below="@+id/crime_list_item_title"
android:layout_alignParentStart="true"/> <CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/crime_solved_label"
android:id="@+id/crime_list_item_solvedCheckBox"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:focusable="false"
/>
</RelativeLayout>

Detail页面CrimePagerActivity,用ViewPager来实现。点击列表项进入相应的Detail页面,页面标题对应相应的Crime Title,向左(向右)进入前一项(后一项)的Detail页面,也就是通过FragmentManager加载相应的CrimeFragment到ViewPager中。

 import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity; import java.util.ArrayList;
import java.util.UUID; public class CrimePagerActivity extends ActionBarActivity { private ViewPager mViewPager;
private ArrayList<Crime> mCrimes; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); mViewPager=new ViewPager(this);
mViewPager.setId(R.id.viewPager);
setContentView(mViewPager); mCrimes=CrimeLab.getInstance(this).getCrimes(); FragmentManager fm=getSupportFragmentManager();
mViewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
@Override
public Fragment getItem(int position) {
Crime crime=mCrimes.get(position);
return CrimeFragment.newInstance(crime.getId());
} @Override
public int getCount() {
return mCrimes.size();
}
}); // 匹配UUID,跳转到当前选中的crime项对应的ViewPager Item
final UUID crimeId=(UUID)getIntent().getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);
for(int i=0;i<mCrimes.size();i++){
if(mCrimes.get(i).getId().equals(crimeId)){
mViewPager.setCurrentItem(i);
setTitle(mCrimes.get(i).getTitle());
break;
}
} // 将当前的ViewPage的Title改为对应的Crime Title
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override
public void onPageSelected(int position) {
Crime crime=mCrimes.get(position);
if(crime.getTitle()!=null){
setTitle(crime.getTitle());
}
} @Override
public void onPageScrollStateChanged(int state) { }
});
}
}

CrimeFragment继承Fragment,点击显示时间的DateButton,弹出DatePickerFragment对话框,用于选择时间,在onActivityResult方法中接收选中的事件信息,并作出响应。此外,为了得到对应的Crime数据,CrimeFragment的类方法newInstance(UUID crimeId)中,在fragment中设置Crime Id作为arguments。以便使用newInstance产生实例,能在onCreate中取回数据,对frament做初始化。

package tina.criminalintent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText; import java.util.Date;
import java.util.UUID; public class CrimeFragment extends Fragment { public static final String EXTRA_CRIME_ID="tina.criminalintent.crime_id";
private static final String DIALOG_DATE="date";
private static final int REQUEST_DATE=0; private Crime mCrime;
private EditText mTitleField;
private Button mDateButton;
private CheckBox mSolvedCheckBox; public CrimeFragment() {
// Required empty public constructor
} public static CrimeFragment newInstance(UUID crimeId){
Bundle args=new Bundle();
args.putSerializable(EXTRA_CRIME_ID,crimeId); CrimeFragment fragment=new CrimeFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); UUID id=(UUID) getArguments().getSerializable(EXTRA_CRIME_ID);
mCrime=CrimeLab.getInstance(getActivity()).getCrime(id); } public void updateDate(){
mDateButton.setText(mCrime.getDate().toString());
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v=inflater.inflate(R.layout.fragment_crime, container, false); mTitleField=(EditText)v.findViewById(R.id.crime_title);
mTitleField.setText(mCrime.getTitle());
mTitleField.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
mCrime.setTitle(s.toString());
} @Override
public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override
public void afterTextChanged(Editable s) { }
}); mDateButton=(Button)v.findViewById(R.id.crime_date);
updateDate();
mDateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager fm=getActivity().getSupportFragmentManager();
DatePickerFragment dialog=DatePickerFragment.newInstance(mCrime.getDate());
dialog.setTargetFragment(CrimeFragment.this,REQUEST_DATE);
dialog.show(fm,DIALOG_DATE);
}
}); mSolvedCheckBox=(CheckBox)v.findViewById(R.id.crime_solved);
mSolvedCheckBox.setChecked(mCrime.isSolved());
mSolvedCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mCrime.setSolved(isChecked);
}
});
return v;
} @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode!= Activity.RESULT_OK)
return; if(requestCode==REQUEST_DATE){
Date date=(Date)data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
mCrime.setDate(date);
updateDate();
}
} }

对应的布局文件fragment_crime.xml如下:

<RelativeLayout 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="tina.criminalintent.CrimeFragment"> <EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/crime_title"
android:hint="@string/crime_title_hint"
android:layout_below="@+id/textView"
android:layout_alignParentStart="true"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/crime_title_label"
android:id="@+id/textView"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
style="?android:listSeparatorTextViewStyle"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/crime_details_label"
android:id="@+id/textView2"
android:layout_below="@+id/crime_title"
android:layout_alignParentStart="true"
style="?android:listSeparatorTextViewStyle"/> <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/crime_date"
android:layout_below="@+id/textView2"
android:layout_centerHorizontal="true"/> <CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/crime_solved_label"
android:id="@+id/crime_solved"
android:layout_below="@+id/crime_date"
android:layout_alignParentStart="true"/>
</RelativeLayout>

在手机横着的时候,需要对布局进行调整。在res文件夹中新建一个Android Resource Directory,name设置为layout-land,resource type选择layout,source set默认为main。注意,项目显示结构选择Project来能看到layout-land文件夹,选择Android的话,会把所有的layout文件都整合显示在layout目录下面。把fragment_crime.xml复制到layout-land文件夹中,对布局进行调整,调整后的布局内容如下:

<RelativeLayout 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="tina.criminalintent.CrimeFragment"> <EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/crime_title"
android:hint="@string/crime_title_hint"
android:layout_below="@+id/textView"
android:layout_alignParentStart="true"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/crime_title_label"
android:id="@+id/textView"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
style="?android:listSeparatorTextViewStyle"/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/crime_details_label"
android:id="@+id/textView2"
android:layout_below="@+id/crime_title"
android:layout_alignParentStart="true"
style="?android:listSeparatorTextViewStyle"/> <LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/textView2"
android:layout_alignParentStart="true"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"> <Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/crime_date"
android:layout_weight="1"/> <CheckBox
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/crime_solved_label"
android:id="@+id/crime_solved"
android:layout_weight="1"
android:layout_marginBottom="78dp"/>
</LinearLayout>
</RelativeLayout>

再回到页面实现,上面提到显示DatePickerFragment对话框,这个对话框继承的是DialogFragment类,使用date数据作为arguments,用一个DatePicker控件来选择日期。

在上面,CrimeFragment用DatePickerFragment的setTargetFragment()方法,指定了DatePickerFragment返回时传递数据给自己。

DatePickerFragment实现了DatePickerDialog.OnDateSetListener这个接口,使得类可以在onDateSet()方法中监听日期的选择,并将用getTargetFragment().onActivityResult(),把时间数据传递给CrimeFragment实例。

 import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.view.View;
import android.widget.DatePicker; import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar; public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener{
public static final String EXTRA_DATE="tina.criminalintent.date"; private Date mDate; public static DatePickerFragment newInstance(Date date){
Bundle args=new Bundle();
args.putSerializable(EXTRA_DATE, date); DatePickerFragment fragment=new DatePickerFragment();
fragment.setArguments(args);
return fragment;
} @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
mDate=(Date)getArguments().getSerializable(EXTRA_DATE);
Calendar calendar=Calendar.getInstance();
calendar.setTime(mDate);
int year=calendar.get(Calendar.YEAR);
final int month=calendar.get(Calendar.MONTH);
final int day=calendar.get(Calendar.DAY_OF_MONTH); return new DatePickerDialog(getActivity(),this,year,month,day);
} @Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mDate = new GregorianCalendar(year, monthOfYear, dayOfMonth).getTime();
if(getTargetFragment()==null)
return; Intent intent=new Intent();
intent.putExtra(EXTRA_DATE,mDate);
getTargetFragment().onActivityResult(getTargetRequestCode(),Activity.RESULT_OK,intent);
} }

至此,Demo的布局文件和Activity设计完毕。

下面是上面的文件中用到的Value文件:

strings.xml

<resources>
<string name="app_name">CriminalIntent</string> <!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="title_activity_crime">CrimeActivity</string> <string name="crime_title_hint">Enter a title for the crime.</string>
<string name="crime_title_label">title</string>
<string name="crime_details_label">details</string>
<string name="crime_solved_label">Solved?</string>
<string name="crimes_title">Crimes</string>
<string name="date_picker_title">Date of crime:</string>
</resources>

还有,为ViewPager创建的ids.xml。由于这里的ViewPager是用代码产生的(mViewPager = new ViewPager(this)),而ViewPager是一个Fragment的Container,必须提供一个resource id才能被FragmentManager使用。

<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="viewPager" type="id"/>
</resources>

至此,Demo结束。

3、Android Studio中的Fragment模板

AndroidStudio中的Fragment(Blank)模板使用的是android.app.Fragment。

Fragment(List)模板是用Frament和布局文件中的ListView相结合,没有直接使用ListFragment,模板里面有很多东西,初看有点复杂,有两个布局文件,分别用于大小屏幕(也就是手机和平板吧),大屏的那个布局文件可以放GridView。

对于上面的Demo,用模板写的CrimeListFragment大致如下:

package tina.criminalintent;

import android.content.Intent;
import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView; import java.util.ArrayList; //
///**
// * A fragment representing a list of Items.
// * <p/>
// * Large screen devices (such as tablets) are supported by replacing the ListView
// * with a GridView.
// * <p/>
// * Activities containing this fragment MUST implement the {@link OnFragmentInteractionListener}
// * interface.
// */
public class CrimeListFragment2 extends Fragment implements AbsListView.OnItemClickListener { private ArrayList<Crime> mCrimes; // private OnFragmentInteractionListener mListener; /**
* The fragment's ListView/GridView.
*/
private AbsListView mListView; /**
* The Adapter which will be used to populate the ListView/GridView with
* Views.
*/
private CrimeAdapter mAdapter; /**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public CrimeListFragment2() {
} @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.crimes_title); mCrimes=CrimeLab.getInstance(getActivity()).getCrimes();
mAdapter=new CrimeAdapter(mCrimes);
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crimelist, container, false); // Set the adapter
mListView = (AbsListView) view.findViewById(android.R.id.list);
((AdapterView) mListView).setAdapter(mAdapter); // Set OnItemClickListener so we can be notified on item clicks
mListView.setOnItemClickListener(this); return view;
} @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Crime crime=((CrimeAdapter)(parent.getAdapter())).getItem(position); // Intent intent=new Intent(getActivity(),CrimeActivity.class);
Intent intent=new Intent(getActivity(),CrimePagerActivity.class);
intent.putExtra(CrimeFragment.EXTRA_CRIME_ID, crime.getId());
startActivity(intent);
} private class CrimeAdapter extends ArrayAdapter<Crime>{
public CrimeAdapter(ArrayList<Crime> crimes) {
super(getActivity(), 0, crimes);
} @Override
public View getView(int position, View convertView, ViewGroup parent) { if(convertView==null){
convertView=getActivity().getLayoutInflater()
.inflate(R.layout.list_item_crime,null);
} Crime c=getItem(position);
TextView titleTextView=(TextView)convertView.findViewById(R.id.crime_list_item_title);
titleTextView.setText(c.getTitle()); TextView dateTextView=(TextView)convertView.findViewById(R.id.crime_list_item_date);
dateTextView.setText(c.getDate().toString()); CheckBox solvedCheckBox=(CheckBox)convertView.findViewById(R.id.crime_list_item_solvedCheckBox);
solvedCheckBox.setChecked(c.isSolved()); return convertView;
}
} @Override
public void onResume() {
super.onResume();
((CrimeAdapter)mListView.getAdapter()).notifyDataSetChanged();
}
}

刚刚接触Fragment,除了模板不兼容Android3.0以下版本以外,我觉得里面的结构也有点复杂,不过Fragment的使用方法很多,具体不知道这种模板是不是用得比较普遍。以后再看吧。

4、运行效果

BNR Android Demo学习笔记(一)——CrimeIntent