碎片是什么
- 嵌在活动当中的UI片段,相当于迷你型活动
- 更合理利用大屏幕
碎片的使用方式
新建LeftFragment类,继承Fragment->新建项目和活动,在活动中增加两个碎片->新建两个碎片类->修改活动
- android:name 显式指明要增加的碎片类名
碎片的生命周期
-
运行
当一个碎片可见,它便是在运行状态,且与它所关联的活动也在运行状态 -
暂停
相关联活动暂停(为占满屏幕的活动被添加到栈顶) -
停止
- 停止形式:相关联的活动进入停止状态,如果有调用addToBackStack,在FragmentTransaction的remove(),replace()从活动中移除碎片前期
- 状态对用户不可见,可能会被系统回收
-
销毁
相关活动销毁,没有调用addToBackStack,在FragmentTransaction的remove()和replace()调用后,进入销毁状态 -
常用的回调方法
Onattach() 碎片和活动建立关联时使用
onCreateView() 为碎片创建视图时使用
onActivityCreate() 与碎片关联的活动完全创建完毕时调用
onDestoryView() 移除与碎片关联的视图
onDtach() 解除关联
动态加载布局的技巧
-
限定符
-
限定页面为单页还是双页
res目录下 两个文件夹:layout 和 layout_large,屏幕大自动加载 layout_large文件夹下的布局,小的加载layout -
最小宽度限定符
在res下新建 layout_sw600dp文件夹 对屏幕宽度最小值设置一个分界点,大于600dp加载一个·布局,小于加载另一个
-
-
动态添加碎片
在程序运行时,动态添加到活动中- 调用beginTransaction() 开启一个事务
- 用replace()向容器内添加或替换碎片,需传入容器id和碎片实例
- commit() 提交事务
//在主类中添加内容
//当左击碎片按钮,右侧碎片替换成AnotherRightFragment
public class Fragment extends AppCompatActivity implements View.OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
Button button=(Button)findViewById(R.id.button);
button.setOnClickListener(new Right_fragment());
}
public void onClick(View view){
switch (view.getId())
case R.id.button:
replacFragment(new AnotherRightFragment());
break;
default:
break;
}
public void replacFragment(Fragment fragment){
// 调用getSupportFragmentManager()方法,获取FragmentManager
FragmentManager fragmentManager=getSupportFragmentManager();
FragmentTransaction transaction=fragmentManager.beginTransaction();
transaction.replace(R.id.right_layout,fragment);
transaction.commit();
}
}
碎片应用之 简易版新闻
gone消失,不占空间,invisility不可见, 占空间,visibility可见,占空间,通过setVisibility 设置
-
inflater.inflate
(resource布局资源id,根视图,false) 将xml转为View对象 -
putExtra(“news_title”,newsTitle) 键值对
增加依赖库
// 在Gradle scripts中找到build.gradle(Module...)增加依赖库
implementation 'androidx.recyclerview:recyclerview:1.0.0'
建News类
public class News {
private String title;
private String content;
public String getTitle(){ //标题
return title;
}
public void setTitle(String title){
this.title=title;
}
public String getContent(){ //内容
return content;
}
public void setContent(String conent){
this.content=conent;
}
}
新闻内容布局
用View
设置细线
<?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">
<LinearLyout
android:id="@+id/visibility_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="20dp">
<TextView
android:id="@+id/news_title"
android:layout_width="match_parent"
android:lauoyt_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:textSize="20sp"/>
<View
android:layout_width="match_parent"
android:layout_heigjt="1dp"
android:background="#000"/>
<TextView
android:id="@+id/news_content"
android:layout_width="match_parent"
android:lauoyt_height="0dp"
android:weight="1"
android:padding="15dp"
android:textSize="18sp"/>
</LinearLyout>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:background="#000"/>
</RelativeLayout>
refresh
将新闻标题内容显示在界面上- findViewById 查找顶层或子层视图,是否存在id符合·条件的View
newsTitleText.setText
刷新
NewsCntentFragment
public class NewsContentFragment extends Fragment {
private View view;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){
view=inflater.inflate(R.layout.news_content,container,false);
return view;
}
//refresh将显示新闻标题内容
public void refresh(String newsTitle,String newsContent){
View visibilityLayout=view.findViewById(R.id.visibility_layout);
visibilityLayout.setVisibility(View.VISIBLE);
TextView newsTitleText=(TextView)view.findViewById(R.id.news_title);
TextView newsContentText=(TextView)view.findViewById(R.id.news_content);
newsTitleText.setText(newsTitle);//刷新标题
newsContentText.setText(newsContent);//刷新内容
}
}
news_content.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<fragment
android:id="@+id/news_content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.fragmentbestpractice.NewsContentFragment"
/>
</LinearLayout>
NewsContentActivity
actionStart
启动活动Intent
获取新闻标题内容
public class NewsContentActivity extends AppCompatActivity {
public static void actionStart(Context context ,String newsTitle,String newsContent){
Intent intent=new Intent(context,NewsContentActivity.class);
intent.putExtra("news_title",newsTitle);
intent.putExtra("news_content",newsContent);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_content);
String newsTitle = getIntent().getStringExtra("news_title"); //获取传入的新闻标题
String newsContent = getIntent().getStringExtra("news_content"); //获取传入的新闻内容
NewsContentFragment newsContentFragment = (NewsContentFragment) getSupportFragmentManager().findFragmentById(R.id.news_content_fragment);
newsContentFragment.refresh(newsTitle,newsContent);//刷新newsContentFragment界面
}
}
news_title_frag
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/news_title_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
news_item.xml
android:padding(Left/Right/Top/Buttom)
控件周围补上空白
android:ellipsize="end"
在尾部进行缩略
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/news_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="18sp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="15dp"
android:paddingBottom="15dp"/>
NewsTitleFragment
NewsTitleFragment中新建一个内部类NewsAdapter
作为RecycleView的适配器 – 直接访问局部变量
public class NewsTitleFragment extends Fragment {
private boolean isTwoPane;
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.news_title_frag,container,false);
RecyclerView newsTitleRecyclerView = (RecyclerView) view.findViewById(R.id.news_title_recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
newsTitleRecyclerView.setLayoutManager(layoutManager);
NewsAdapter adapter = new NewsAdapter(getNews());
newsTitleRecyclerView.setAdapter(adapter);
return view;
}
private List<News> getNews() {
List<News> newsList = new ArrayList<>();
for(int i = 1;i <= 50; i++){
News news = new News();
news.setTitle("This is news title" +i);
news.setContent(getRandomLengthContent("This is news content"+i+"."));
newsList.add(news);
}
return newsList;
}
private String getRandomLengthContent(String content) {
Random random = new Random();
int length = random.nextInt(20) + 1;
StringBuilder builder = new StringBuilder();
for(int i = 0;i < length; i++){
builder.append(content);
}
return builder.toString();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(getActivity().findViewById(R.id.news_content_layout) != null){
isTwoPane = true; //可以找到news_content_layout布局时,为双页模式
}else{
isTwoPane = false; //找不到为单页模式
}
}
class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder>{
private List<News> mNewsList;
class ViewHolder extends RecyclerView.ViewHolder{
TextView newsTitleText;
public ViewHolder(View view) {
super(view);
newsTitleText = (TextView)view.findViewById(R.id.news_title);
}
}
public NewsAdapter(List<News> newsList){
mNewsList = newsList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item,parent,false);
final ViewHolder holder = new ViewHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
News news = mNewsList.get(holder.getAdapterPosition());//
if(isTwoPane){ //如果是双页模式,刷新NewsContentFragment中的内容
NewsContentFragment newsContentFragment = (NewsContentFragment) getFragmentManager().findFragmentById(R.id.news_content_fragment);
newsContentFragment.refresh(news.getTitle(),news.getContent());
}else{ //如果是单页模式,直接启动NewsContentActivity
NewsContentActivity.actionStart(getActivity(),news.getTitle(),news.getContent());
}
}
});
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
News news = mNewsList.get(position);
holder.newsTitleText.setText(news.getTitle());
}
@Override
public int getItemCount() {
return mNewsList.size();
}
}
}
layout-sw600dp/activity_main.xml
- res -> Android Resource Directory ->layout-sw600dp->Project中建activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/news_title_fragment"
android:name="com.example.fragmentbestpractice.NewsContentFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<FrameLayout
android:id="@+id/news_content_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3">
<fragment
android:id="@+id/news_content_fragment"
android:name="com.example.fragmentbestpractice.NewsContentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>