博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BNR Android Demo学习笔记(一)——CrimeIntent
阅读量:6603 次
发布时间:2019-06-24

本文共 19637 字,大约阅读时间需要 65 分钟。

开发环境: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
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
(); 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
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,可以参考这篇文章。需要注意的是,有关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里面不放置任何子控件。

上面有了基本的模板了,接下来就是第一个页面啦。应用一打开,就是一个列表页面,显示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
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
{ public CrimeAdapter(ArrayList
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如下:

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
mCrimes;16 17 @Override18 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 @Override30 public Fragment getItem(int position) {31 Crime crime=mCrimes.get(position);32 return CrimeFragment.newInstance(crime.getId());33 }34 35 @Override36 public int getCount() {37 return mCrimes.size();38 }39 });40 41 // 匹配UUID,跳转到当前选中的crime项对应的ViewPager Item42 final UUID crimeId=(UUID)getIntent().getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);43 for(int i=0;i
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如下:

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

 再回到页面实现,上面提到显示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     @Override34     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     @Override46     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

CriminalIntent
Hello blank fragment
CrimeActivity
Enter a title for the crime.
title
details
Solved?
Crimes
Date of crime:

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

至此,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.// * 

// * Large screen devices (such as tablets) are supported by replacing the ListView// * with a GridView.// *

// * Activities containing this fragment MUST implement the {@link OnFragmentInteractionListener}// * interface.// */public class CrimeListFragment2 extends Fragment implements AbsListView.OnItemClickListener { private ArrayList
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
{ public CrimeAdapter(ArrayList
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、运行效果

转载于:https://www.cnblogs.com/tt2015-sz/p/4647609.html

你可能感兴趣的文章
sturts漏洞
查看>>
java静态方法中读取类路径
查看>>
UNIX网络编程(第三版 ) 测试代码 7.2
查看>>
【原创】数组完整篇 / 基本操作/ 进阶 / 遍历 / 实例 / 拓展 / 取 / 赋
查看>>
Eclipse 实用快捷键大全
查看>>
我原来是一个伪无神论者
查看>>
linux 挂载samba盘
查看>>
cookie 双引号
查看>>
LayaAir 旋转的小球 抛物线效果 [未完善]
查看>>
cdn的具体应用案例
查看>>
android的selector(背景选择器)
查看>>
more adj/adv than as well as prefer to
查看>>
pitfall fields
查看>>
Hadoop实战读书笔记(3)
查看>>
策略模式
查看>>
2012-2013 微软商业智能大调研分析报告
查看>>
iOS7设计规范分享:UI设计基础
查看>>
徐元杰:“淘”里“淘”外,简单营销
查看>>
国内外SNS比较分析
查看>>
iOS Image Filters
查看>>