• 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中。

     1 import android.os.Bundle;
     2 import android.support.v4.app.Fragment;
     3 import android.support.v4.app.FragmentManager;
     4 import android.support.v4.app.FragmentStatePagerAdapter;
     5 import android.support.v4.view.ViewPager;
     6 import android.support.v7.app.ActionBarActivity;
     7 
     8 
     9 import java.util.ArrayList;
    10 import java.util.UUID;
    11 
    12 public class CrimePagerActivity extends ActionBarActivity {
    13 
    14     private ViewPager mViewPager;
    15     private ArrayList<Crime> mCrimes;
    16 
    17     @Override
    18     protected void onCreate(Bundle savedInstanceState) {
    19         super.onCreate(savedInstanceState);
    20 
    21         mViewPager=new ViewPager(this);
    22         mViewPager.setId(R.id.viewPager);
    23         setContentView(mViewPager);
    24 
    25         mCrimes=CrimeLab.getInstance(this).getCrimes();
    26 
    27         FragmentManager fm=getSupportFragmentManager();
    28         mViewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
    29             @Override
    30             public Fragment getItem(int position) {
    31                 Crime crime=mCrimes.get(position);
    32                 return CrimeFragment.newInstance(crime.getId());
    33             }
    34 
    35             @Override
    36             public int getCount() {
    37                 return mCrimes.size();
    38             }
    39         });
    40 
    41 //        匹配UUID,跳转到当前选中的crime项对应的ViewPager Item
    42         final UUID crimeId=(UUID)getIntent().getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);
    43         for(int i=0;i<mCrimes.size();i++){
    44             if(mCrimes.get(i).getId().equals(crimeId)){
    45                 mViewPager.setCurrentItem(i);
    46                 setTitle(mCrimes.get(i).getTitle());
    47                 break;
    48             }
    49         }
    50 
    51 //        将当前的ViewPage的Title改为对应的Crime Title
    52         mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    53             @Override
    54             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    55 
    56             }
    57 
    58             @Override
    59             public void onPageSelected(int position) {
    60                 Crime crime=mCrimes.get(position);
    61                 if(crime.getTitle()!=null){
    62                     setTitle(crime.getTitle());
    63                 }
    64             }
    65 
    66             @Override
    67             public void onPageScrollStateChanged(int state) {
    68 
    69             }
    70         });
    71     }
    72 }
    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实现了DatePickerDialog.OnDateSetListener这个接口,使得类可以在onDateSet()方法中监听日期的选择,并将用getTargetFragment().onActivityResult(),把时间数据传递给CrimeFragment实例。

     1 import android.app.Activity;
     2 import android.app.AlertDialog;
     3 import android.app.DatePickerDialog;
     4 import android.app.Dialog;
     5 import android.content.DialogInterface;
     6 import android.content.Intent;
     7 import android.os.Bundle;
     8 import android.support.v4.app.DialogFragment;
     9 import android.util.Log;
    10 import android.view.View;
    11 import android.widget.DatePicker;
    12 
    13 import java.util.Calendar;
    14 import java.util.Date;
    15 import java.util.GregorianCalendar;
    16 
    17 
    18 public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener{
    19     public static final String EXTRA_DATE="tina.criminalintent.date";
    20 
    21     private Date mDate;
    22 
    23     public static DatePickerFragment newInstance(Date date){
    24         Bundle args=new Bundle();
    25         args.putSerializable(EXTRA_DATE, date);
    26 
    27         DatePickerFragment fragment=new DatePickerFragment();
    28         fragment.setArguments(args);
    29         return fragment;
    30     }
    31 
    32 
    33     @Override
    34     public Dialog onCreateDialog(Bundle savedInstanceState) {
    35         mDate=(Date)getArguments().getSerializable(EXTRA_DATE);
    36         Calendar calendar=Calendar.getInstance();
    37         calendar.setTime(mDate);
    38         int year=calendar.get(Calendar.YEAR);
    39         final int month=calendar.get(Calendar.MONTH);
    40         final int day=calendar.get(Calendar.DAY_OF_MONTH);
    41 
    42         return new DatePickerDialog(getActivity(),this,year,month,day);
    43     }
    44 
    45     @Override
    46     public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
    47         mDate = new GregorianCalendar(year, monthOfYear, dayOfMonth).getTime();
    48         if(getTargetFragment()==null)
    49             return;
    50 
    51         Intent intent=new Intent();
    52         intent.putExtra(EXTRA_DATE,mDate);
    53         getTargetFragment().onActivityResult(getTargetRequestCode(),Activity.RESULT_OK,intent);
    54     }
    55 
    56 }
    View Code

    至此,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的使用方法很多,具体不知道这种模板是不是用得比较普遍。以后再看吧。

    4、运行效果

  • 相关阅读:
    python基础6 迭代器 生成器
    Netty入门之客户端与服务端通信(二)
    Netty入门之HelloWorld
    Java并发之BlockingQueue的使用
    Java并发之Semaphore的使用
    Java并发之CyclicBarria的使用(二)
    Java并发之CyclicBarria的使用
    Java并发之CountDownLatch的使用
    MongoDB的下载与安装
    Hibernate5.2之反向工程
  • 原文地址:https://www.cnblogs.com/tt2015-sz/p/4647609.html
Copyright © 2020-2023  润新知