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

开发环境: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;

    }

}
View Code

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;

    }

}
View Code

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();

        }

    }

}
View Code

其对应的布局文件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中。

package tina.criminalintent;





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;



/**

 * Created by CW3479 on 2015/7/14.

 */

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);

                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) {



            }

        });

    }

}
View Code

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();

        }

    }





}
View Code

对应的布局文件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则用getTargetFragment().onActivityResult(),把时间数据传递给CrimeFragment实例。

package tina.criminalintent;



import android.app.Activity;

import android.app.AlertDialog;

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;



/**

 * Created by CW3479 on 2015/7/14.

 */

public class DatePickerFragment extends DialogFragment {

    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);



        View v=getActivity().getLayoutInflater().inflate(R.layout.dialog_date, null);



        DatePicker datePicker=(DatePicker)v.findViewById(R.id.dialog_date_picker);

        datePicker.init(year, month, day, new DatePicker.OnDateChangedListener() {

            @Override

            public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

                mDate = new GregorianCalendar(year, monthOfYear, dayOfMonth).getTime();



//                把数据保存到arguments中,以便设备旋转引起Fragment销毁重建时数据保持一致

                getArguments().putSerializable(EXTRA_DATE, mDate);

            }

        });

        return new AlertDialog.Builder(getActivity())

                .setView(v)

                .setTitle(R.string.date_picker_title)

                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

                    @Override

                    public void onClick(DialogInterface dialog, int which) {

                        sendResult(Activity.RESULT_OK);

                    }

                })

                .create();

    }



    private void sendResult(int resultCode){

        if(getTargetFragment()==null)

            return;



        Intent intent=new Intent();

        intent.putExtra(EXTRA_DATE,mDate);

        getTargetFragment().onActivityResult(getTargetRequestCode(),resultCode,intent);

    }



}
View Code

对应的布局文件dialog_date.xml如下,只放了一个DatePicker控件:

<?xml version="1.0" encoding="utf-8"?>

<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:id="@+id/dialog_date_picker">



</DatePicker>

至此,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();

    }

}
View Code

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

你可能感兴趣的:(android)