最近利用下班时间,找了看什么书比较适合初学android的朋友,很多人推荐了《第一行代码》这本书,于是就买了一本,感觉看书,思考,动手,再思考和总结这样过程还是很有必要的,于是就打算把自己学习的东西简单的总结一下;方便自己以后查找,也有利于学习的巩固。在这里首先要感谢一下书籍的作者——郭霖前辈
关于碎片这一块,我只用了两篇来介绍,一篇是基础知识,一篇是应用示例,下面就来看看碎片的基本知识吧。示例代码下载链接
1,碎片(Fragment)
其主要的作用是兼顾平板这种大屏设备的UI展示,是一种可以嵌入在活动当中的UI片段,可有更好帮助我们利用不同屏幕尺寸的UI显示。这里,(其实主要就是针对平板,所以这也是为什么我们待会要专门创建一个平板模拟器来运行程序)。
(1)碎片的简单用法的使用步骤入下:
- 第一步:创建一个想要通过碎片展示的自定义布局
- 第二步:自定义一个类继承Fragment(support-v4包),并重写里面的onCreateView()方法,实现对自定义布局的加载
- 第三步:在活动的布局中通过fragment标签引入要添加的碎片(具体实通过其中的android:name属性来指定自定义的Fragment类)
(2)碎片的动态加载使用步骤如下:
- 第一步:前三步不变,在第三步的时候,我们不是直接通过fragment标签来引入要添加的碎片,因为我们是动态加载,所以,这个时候需要把原有的fragment标签换成一个可以装在碎片的容器,然后在布局对应的活动中通过逻辑来实现动态加载;通常这个容器可以是FrameLayout
- 第二步:在活动中,获取装载碎片的容器实例,在加载的逻辑中执行下面几步(书中内容)
- 第三步:创建带添加的碎片实例(也就是我们自定义Fragment类的对象)
- 第四步:在活动中通过getSupportFragmentManager()获取FragmentManager对象
- 第五步:开启事务(beginTransaction())
- 第六步:向第二步中获取的容器中添加或者替换碎片(replace())
- 第七步:提交事务(commit())
(3)在碎片中模拟返回栈(也是我常常说的任务栈,尤其是在活动的启动方式中说的最多,可以点击查看)
其实现步骤和上面几乎一样,只需要在提交事务前执行一下addToBackStack()把事务添加到返回栈中即可。
(4)碎片与活动以及碎片与碎片之间的通信
- 第一步:首先我们知道在活动中可以通过getSupportFragmentManager()方法获取FragmentManager实例,而FragmentManager提供了一个类似于findViewById()的findFragmentById()方法来获取碎片实例,所以活动中可以调用碎片的方法
- 第二步:在碎片中,我们可以通过getActivity()方法来获取当前碎片关联(onAttach())的活动实例,所以碎片中可以调用活动的方法
- 第三步:碎片与碎片之间的通信,我想就不用再多说了吧。我们只需要把活动当做一个桥梁就可以啦。
(5)碎片的生命周期
一个碎片的生命周期状态可以有以下四种(和活动一样):
- 运行状态
- 暂停状态
- 停止状态
- 销毁状态
与碎片生命周期相关的方法有:
- onAttach()
- onCreate()
- onStart()
- onCreateView()
- onActivityCreated()
- onResume()
- onPuase()
- onStop()
- onDestroyView()
- onDestroy()
- onDetach()
和活动的生命周期很类似,但是更复杂一点,其实也不怪,毕竟他是依托于活动来显示的,所以其状态判断还要考虑活动的状态,自然是要复杂一点的。建议参考官方文档的Fragment什么周期图。
(6)动态加载布局的技巧
a,使用限定符:
在res目录下面新建一个layout-large文件夹,在里面新建和layout文件夹中相同的活动布局名称,只不过界面显示对应于大屏幕内容,而layout中同名称活动布局显示小屏幕内容,至于活动加载哪一个文件夹下面的布局文件,由其自己决定。这种方式可控性不好
b,使用最小宽度限定符(Smallest-width Qualifier):
上面也说到简单限定符对加载布局的控制不是很好,这种方式就能很准确的规定在屏幕尺寸多少的情况下加载何种布局,比如在res下面命名一个layout-sw400dp文件夹,就表示在设备宽度大于400dp的时候就加载该文件夹下面的布局文件
2,示例代码
有点多,其实我并不是太想复制粘贴上来,更建议下载源码(点击下载):
Mainactivity.java代码:
package com.hfut.operationfragment;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void simpleFragment(View view){
intent=new Intent(this,SimpleFragment.class);
startActivity(intent);
}
public void dynamicFragment(View view){
intent=new Intent(this,DynamicFragment.class);
startActivity(intent);
}
public void simulateTaskStack(View view){
intent=new Intent(this,SimulateTaskStack.class);
startActivity(intent);
}
public void fragmentLifespace(View view){
intent=new Intent(this,FragmentLifespace.class);
startActivity(intent);
}
}
LeftFragment.java代码:
package com.hfut.operationfragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* author:why
* created on: 2018/4/7 10:59
* description:
*/
public class LeftFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.left_fragemnt,container,false);
return view;
}
}
RightFragment.java代码:
package com.hfut.operationfragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* author:why
* created on: 2018/4/7 11:00
* description:
*/
public class RightFragemnt extends Fragment {
private static final String TAG = "RightFragemnt";
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.right_fragment,container,false);
Log.i(TAG, "onCreateView: ");
return view;
}
@Override
public void onAttach(Context context) {
Log.i(TAG, "onAttach: ");
super.onAttach(context);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.i(TAG, "onCreate: ");
super.onCreate(savedInstanceState);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Log.i(TAG, "onActivityCreated: ");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
Log.i(TAG, "onStart: ");
super.onStart();
}
@Override
public void onResume() {
Log.i(TAG, "onResume: ");
super.onResume();
}
@Override
public void onPause() {
Log.i(TAG, "onPause: ");
super.onPause();
}
@Override
public void onStop() {
Log.i(TAG, "onStop: ");
super.onStop();
}
@Override
public void onDestroyView() {
Log.i(TAG, "onDestroyView: ");
super.onDestroyView();
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy: ");
super.onDestroy();
}
@Override
public void onDetach() {
Log.i(TAG, "onDetach: ");
super.onDetach();
}
}
SimpleFragment.java代码:
package com.hfut.operationfragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class SimpleFragment extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_fragment);
}
}
DynamicFragment.java代码:
package com.hfut.operationfragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class DynamicFragment extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_fragment);
Button button=findViewById(R.id.news1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
changeFragment(new FirstNewsFregment());
}
});
changeFragment(new RightFragemnt());
}
public void changeFragment(Fragment fragment){
FragmentManager manager=getSupportFragmentManager();
FragmentTransaction transaction=manager.beginTransaction();
//注意,第一个参数接收的是装载Fragment的容器id
transaction.replace(R.id.right_fragment,fragment);
transaction.commit();
}
}
SimulateTaskStack.java代码:
package com.hfut.operationfragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class SimulateTaskStack extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simulate_task_stack);
Button button=findViewById(R.id.news1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
changeFragment(new FirstNewsFregment());
}
});
changeFragment(new RightFragemnt());
}
public void changeFragment(Fragment fragment){
FragmentManager manager=getSupportFragmentManager();
FragmentTransaction transaction=manager.beginTransaction();
transaction.replace(R.id.right_fragment,fragment);
//加上之后就可以模拟返回栈了
transaction.addToBackStack(null);
transaction.commit();
}
}
FragmentLifespace.java代码:
package com.hfut.operationfragment;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class FragmentLifespace extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_lifespace);
}
public void back(View view){
Intent intent=new Intent(this,MainActivity.class);
startActivity(intent);
}
}
FirstNewsFragment代码:
package com.hfut.operationfragment;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class FragmentLifespace extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_lifespace);
}
public void back(View view){
Intent intent=new Intent(this,MainActivity.class);
startActivity(intent);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.hfut.operationfragment.MainActivity">
<Button
android:layout_marginTop="30dp"
android:text="碎片布局简单实现"
android:textSize="20dp"
android:onClick="simpleFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:layout_marginTop="10dp"
android:text="动态加载碎片布局"
android:textSize="20dp"
android:onClick="dynamicFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:layout_marginTop="10dp"
android:text="碎片中模拟任务栈"
android:textSize="20dp"
android:onClick="simulateTaskStack"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:layout_marginTop="10dp"
android:text="体验碎片的生命周期"
android:textSize="20dp"
android:onClick="fragmentLifespace"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
left_fragment.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#FFA500"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/news1"
android:textSize="20dp"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:text="News1"
android:textAllCaps="false" />
<Button
android:textSize="20dp"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="News2"
android:textAllCaps="false" />
<Button
android:textSize="20dp"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="News3"
android:textAllCaps="false" />
<Button
android:textSize="20dp"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="News4"
android:textAllCaps="false" />
</LinearLayout>
right_fragment.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#00BFFF"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_marginTop="30dp"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/news"/>
<TextView
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="今天的主要内容有..."/>
</LinearLayout>
activity_simple_fragment.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.hfut.operationfragment.SimpleFragment">
<fragment
android:id="@+id/left_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:name="com.hfut.operationfragment.LeftFragment"
android:layout_weight="1">
</fragment>
<fragment
android:id="@+id/right_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:name="com.hfut.operationfragment.RightFragemnt"
android:layout_weight="3">
</fragment>
</LinearLayout>
activity_dynamic_fragment.java代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.hfut.operationfragment.DynamicFragment">
<fragment
android:id="@+id/left_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:name="com.hfut.operationfragment.LeftFragment"
android:layout_weight="1">
</fragment>
<FrameLayout
android:id="@+id/right_fragment"
android:layout_weight="3"
android:layout_width="0dp"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
activity_simulate_task_stack.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hfut.operationfragment.SimulateTaskStack">
<fragment
android:id="@+id/left_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:name="com.hfut.operationfragment.LeftFragment"
android:layout_weight="1">
</fragment>
<FrameLayout
android:id="@+id/right_fragment"
android:layout_weight="3"
android:layout_width="0dp"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
activity_fragment_lifespace.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.hfut.operationfragment.FragmentLifespace">
<TextView
android:layout_marginTop="30dp"
android:textSize="20dp"
android:text="逗比,直接在第三个练习里面就可以完成了,还不返回查看一下"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:layout_marginTop="10dp"
android:src="@drawable/ironic"
android:layout_gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="400dp" />
<Button
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="back"
android:text="返回"
android:textSize="20dp" />
</LinearLayout>
right_dynamic.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#FF6347"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_marginTop="30dp"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/news1"/>
<TextView
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="今天的主要内容有..."/>
</LinearLayout>
主配置文件AndroidManifest.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hfut.operationfragment">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SimpleFragment" />
<activity android:name=".DynamicFragment" />
<activity android:name=".SimulateTaskStack" />
<activity android:name=".FragmentLifespace"></activity>
</application>
</manifest>
真的有点多了,所以建议学习还是直接下载源码比较好一点。
3,运行结果
第一步:运行程序
第二步:点击“碎片布局简单实现”,然后返回
第三步:点击“动态加载碎片布局”,点击“News1”,返回至主界面
第四步:点击“碎片中模拟任务栈”,点击“News1”,返回至主界面
第五步:点击“体验碎片的生命周期”,返回主界面,重复第四步哈哈
总结:这部分零散的知识还是蛮多的,我没有仔细的展开。源码下载地址
注:欢迎扫码关注