首页 > 编程知识 正文

Android课程总结,android技术总结

时间:2023-05-03 18:13:34 阅读:212188 作者:1954

Android学习总结

activity是Android SDK中Activity的一个实例,负责控制各组件与用户的交互

布局定义了一系列组件,包括Button、TextView、 RecyclerView。布局和组件之间的关系可用下图表示:

常用组件和布局的继承关系如下图:

3. 项目的app/res/values目录下保存了一系列的资源,包括字符串资源,图片资源等,包括布局也是资源的一种。它们都通过资源ID被引用。如果控件也需要被引用,则在xml文件中定义它们时,可以加上android:id属性,为其设置ID。
4. xml布局是如何转换为视图对象的呢?activity子类被创建后,onCreate(Bundle)方法会被调用,它再调用

public void setContentView(int layoutRestId)

根据传入的布局资源ID,使用LayoutInflater类实例化该布局中定义的每一个View。activity子类都需要声明在AndroidManifest.xml配置文件中,在该文件中会设置一个launcher activity,app启动时会创建该activity。
5. MVC设计模式。MVC即模型,视图,控制,activity或者fragment(service还未学习)可以作为控制器,它们将视图即View实例对象显示在屏幕,将模型(实例类)中的数据显示更新在屏幕上。GeoQuiz项目的MVC示意图如下:

6. activity的生命周期。

在activity的各个阶段,Android系统会自动调用相应的方法。重载这些方法,添加log,切换手机横竖屏,可以通过logcat看到activity的生命周期中相应方法的调用。
7. 保存数据以应对设备旋转。

protected void onSaveInstanceState(Bundle outstate)

该方法通常在onStop()方法前被调用,除非用户按了后退键。该方法的默认实现把所有activity视图状态保存在Bundle中,Bundle是一种存储键-值对的一种结构。可以通过覆盖onSaveInstanceState()方法,将一些信息保存在Bundle中:

@Overridepublic void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); Log.i(TAG, "onSaveInstanceState"); savedInstanceState.putInt(KEY_INDEX, mCurrentIndex); savedInstanceState.putBoolean(KEY_IS_CHEATER, mIsCheater);}

在onCreate()方法中获取信息:

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "onCreate(Bundle) called"); setContentView(R.layout.activity_quiz); if (savedInstanceState != null) { mCurrentIndex = savedInstanceState.getInt(KEY_INDEX); mIsCheater = savedInstanceState.getBoolean(KEY_IS_CHEATER); } ...}

还可以存BooleanArray。操作系统会将Bundle对象放入activity记录中,可以理解为暂存。覆盖onSaveInstanceState()保存当前activity的小的或状态的数据;覆盖onStop()方法,保存永久性数据,如用户编辑的文字等。(?如何理解?)
8. tools命名空间。使用该命名空间,可以覆盖某个组件的任意属性,改属性仅在预览中生效。
9. 启动activity并互相传递数据。一个activity启动另一个activity最简单的方式是用startActivity方法:

public void startActivity(Intent intent)

activity调用该方法后,调用请求发给了操作系统的ActivityManager。ActivityManager启动哪个activity呢?答案在传入的参数intent。intent有很多构造方法,其中一种为:

public Intent(Context packageContext, Class<?> cls)

传入的Class类型参数告诉ActivityManager要启动的activity,Context类型参数告诉ActivityManager在哪里可以找到它(?不是在manifest配置文件中声明了吗?)。可以在startActivity(Intent intent)的intent上附加上extra信息,传递给启动的activity。如同在Bundle中保存信息一样,extra信息也是一种键值对,在子activity中提供一个借口,父activity把信息通过借口传过来即可,无需关心“键”是什么样的:

//子activitypublic static Intent newIntent(Context packageContext, boolean answerIsTrue) { Intent intent = new Intent(packageContext, CheatActivity.class); intent.putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue); return intent;}//父activitymCheatButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //start cheatactivity boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue(); Intent intent = CheatActivity.newIntent(QuizActivity.this, answerIsTrue); startActivity(intent); }});

子activity在onCreate方法中就可以获取该extra信息:

mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);

可以用intent传递更多的信息,使用多参数版本的intent构造函数即可(还未实践)。

以上是父activity传递信息给子activity,要获取子activity的信息,可以修改startActivity方法:

startActivityForResult(intent, REQUEST_CODE_CHEAT);

子activity可以调用:

public final void setResult(int resultCode)public final void setResult(int resultCode, Intent intent)

如果子activity没有调用setResult,而父activity又是调用startActivityForResult启动子activity的,父activity会收到Activity.RESULT_CANCELLED。在项目实践中,子activity的Button监听回调被调用后,它设置了返回结果:

private void setAnswerShownResult(boolean isAnswerShown) { Intent intent = new Intent(); intent.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown); setResult(RESULT_OK, intent);}public static boolean wasAnswerShown(Intent result) { return result.getBooleanExtra(EXTRA_ANSWER_SHOWN, false);}

父activity要重载onActivityResult()方法:

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != Activity.RESULT_OK) { return; } if (requestCode == REQUEST_CODE_CHEAT) { if (data == null) { return; } mIsCheater = CheatActivity.wasAnswerShown(data); }}

这里,解析信息放在了子activity定义的一个接口中,因为“键”存在子activity中,最终的还是通过intent来解析到的。
10. Fragment。fragment与activity很类似,它也是负责创建并管理用户界面,与模型对象进行交互。fragment的生命周期与activity类似,但是fragment的生命周期方法由它的托管activity而不是操作系统调用。fragment并没有像activity一样在onCreate方法中完成布局和组件view的实例化,而是在onCreateView方法中完成的,如下:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_crime, container, false); mTitleField = v.findViewById(R.id.crime_title); ... mDateButton = v.findViewById(R.id.crime_date); ... mSolvedCheckBox = v.findViewById(R.id.crime_solved); ... return v;}

第二个参数是视图的父视图。以上fragment类中完成了主要的工作,但它的视图显然还无法显示出来,它需要托管给activity。Activity类中添加了FragmentManager类,它负责管理fragment并将它们的视图添加到activity的视图层级结构中。具体做法:

public class CrimeActivity extends SingleFragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment); FragmentManager fm = getSupportFragmentManager(); Fragment fragment = fm.findFragmentById(R.id.fragment_container); if (fragment == null) { fragment = new createFragment(); fm.beginTransaction() .add(R.id.fragment_container, fragment) .commit(); } }}

fragment事务的add接口,第一个参数为容器视图资源ID,第二个参数是要加入的Fragment。二者视图关系可用下图表示,fragment视图要放置在activity的视图层级结构中:

11. RecyclerView。RecyclerView是ViewGroup的子类,每一个列表项是作为View子对象来显示的。它们的显示依赖于两个类:ViewHolder和Adapter。在控制器中重载这两个类。实践项目中RecyclerView作为fragment布局的一个组件,在onCreateView方法中要先调用:

mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

接下来,控制器把要显示的模型对象(一般是ArrayList对象?)作为参数构造了一个Adapter,然后调用:

mCrimeRecyclerView.setAdapter(mAdapter);

接着,Adapter调用getItemCount()方法获取要显示的列表项的个数,根据该个数,循环调用onCreateViewHolder( ViewGroup viewGroup, int i)和onBindViewHolder(CrimeHolder crimeHolder, int i)。ViewHolder的任务是什么呢?它首先会把列表项布局实例化,然后再通过各组件的ID,找到它们的引用。在onBindViewHolder,Adapter会把要显示的模型参数传递给ViewHolder,它通过组件显示在屏幕上。项目实践中相关代码示例:

private class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener { ...... public CrimeHolder(LayoutInflater inflater, ViewGroup parent) { super(inflater.inflate(R.layout.list_item_crime, parent, false)); itemView.setOnClickListener(this); mTitleTextView = itemView.findViewById(R.id.crime_title); mDateTextView = itemView.findViewById(R.id.crime_date); mSolvedImageView = itemView.findViewById(R.id.crime_solved); } public void bind(Crime crime) { mCrime = crime; mTitleTextView.setText(mCrime.getTitle()); mDateTextView.setText(mCrime.getDate().toString()); mSolvedImageView.setVisibility(mCrime.isSolved() ? View.VISIBLE : View.GONE); } ......}@Overrideprivate class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> { ...... public CrimeHolder onCreateViewHolder( ViewGroup viewGroup, int i) { LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); return new CrimeHolder(layoutInflater, viewGroup); } @Override public void onBindViewHolder(CrimeHolder crimeHolder, int i) { Crime crime = mCrimes.get(i); crimeHolder.bind(crime); } ......}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。