读了郭神的第一行代码,敲完新闻项目之后又重新捋了下思路。才明白整个小项目的流程,下面分享给大家:
首先:我们的需求:1. 分清楚双页模式和单页模式。让项目可以一套代码运行; 2. 单页模式下,有一个新闻列表,点击里面的新闻标题跳转到新闻详情页; 3. 双页模式下,左边是新闻列表,右边是新闻详情,点击左边的新闻列表,右边的新闻详情随之更新。
ok,需求清楚了,下面就开始敲代码
新建完项目,在activity_main里面放一个碎片,作为单页模式的新闻列表
新建NewsTitleFragment
public class NewsTitleFragment extends Fragment {
private View view;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.news_title_list, container, false);
return view;
}
这个NewsTitleFragment里面只要有一个列表用来显示新闻标题就行,(这个fragment是可以再双页模式中复用的)
新建news_title_list布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_news_list"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
新建List_item布局,用来显示新闻标题的样式
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:paddingBottom="15dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="15dp"
android:singleLine="true"
android:textSize="18dp">
</TextView>
在activity_main里面放一个碎片,作为单页模式的新闻列表
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/news_title_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/news_title_fragment"
android:name="com.yiyajing.mypremission.fragment.NewsTitleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
下面开始编辑新闻列表
首先新建一个新闻的实体类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 content) {
this.content = content;
}
}
编辑NewsTitleFragment的adapter和内容
public class NewsTitleFragment extends Fragment {
private boolean isTwoPane;
private List<News> news;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.news_title_list, container, false);
//找到RecyclerView布局
RecyclerView newsTitleRecyclerView = (RecyclerView) view.findViewById(R.id.rv_news_list);
//设置方向
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
newsTitleRecyclerView.setLayoutManager(linearLayoutManager);
//实例adapter
NewsAdapter adapter = new NewsAdapter(getNews());
newsTitleRecyclerView.setAdapter(adapter);
return view;
}
/**
* fragment的生命周期之一
* 在与之相关联的activity创建完毕的时候调用它
*/
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//判断是否为双页模式
if (getActivity().findViewById(R.id.news_content_layout) != null) {
isTwoPane = true;//双页模式
} else {
isTwoPane = false;//单页模式
}
}
/**
* 创建集合,填充数据
*/
public List<News> getNews() {
//创建集合
List<News> mList = new ArrayList<>();
//实例化数据
for (int i = 0; i <= 100; i++) {
News mNews = new News();
mNews.setTitle("This is Title" + i);
mNews.setContent(getRandomLengthContent("This is content" + i + "."));
mList.add(mNews);
}
return mList;
}
/**
* 生成随机数量的新闻内容
*/
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();
}
/**
* RecycleView的适配器
*/
class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {
private List<News> newsList;
public NewsAdapter(List<News> newsList) {
this.newsList = newsList;
}
@Override
public NewsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//1. 加载布局
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.news_title_list_item, parent, false);
//2. 每个item的点击事件
final ViewHolder holder = new ViewHolder(view);
holder.newsTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
News news = newsList.get(holder.getAdapterPosition());
if (isTwoPane) {
//如果是双页模式,就刷新newsCongtentFragment里面的内容
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(NewsAdapter.ViewHolder holder, int position) {
News news = newsList.get(position);
holder.newsTitle.setText(news.getTitle());
}
@Override
public int getItemCount() {
return newsList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView newsTitle;
public ViewHolder(View itemView) {
super(itemView);
newsTitle = (TextView) itemView.findViewById(R.id.item_tv_title);
}
}
}
}
这里面就涉及到了双页模式的刷新和单页模式的跳转
首先双页模式的刷新
新建NewsContentFragment新闻详情页
public class NewsContentFragment extends Fragment {
private TextView newsTvTitle;
private TextView newsTvContent;
private View view;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.news_fragment_flag, container, false);
return view;
}
/**
* 这个方法用来刷新新闻详情
*/
public void refresh(String title, String content) {
newsTvTitle = (TextView) view.findViewById(R.id.news_tv_title);
newsTvContent = (TextView) view.findViewById(R.id.news_tv_content);
newsTvTitle.setText(title);
newsTvContent.setText(content);
}
}
新建详情页的布局news_fragment_flag
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/news_tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:text="标题"
android:textColor="#f00"
android:textSize="24dp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000" />
<TextView
android:id="@+id/news_tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="内容"
android:textSize="20dp" />
</LinearLayout>
在adapter里面调用NewsContentFragment的refresh方法就可以实现更新
下面是双页模式
首先看过前几页第一行代码的敲友应该可以知道,在res下面新建layout-sw600dp文件夹系统就在屏幕分辨率大于600的时候自动选择该文件夹下的文件,在文件夹下面新建activity_main文件。(这里面有个坑,请绕行,我们新建的是layout-sw600dp文件夹,不是layout_sw600dp。layout后面不是下划线,是杠,是杠,是杠!)
新建activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<fragment
android:id="@+id/news_title_fragment"
android:name="com.yiyajing.mypremission.fragment.NewsTitleFragment"
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.yiyajing.mypremission.fragment.NewsContentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
双页模式情况下,系统会自动选择该布局。
下面是单页模式情况下的跳转,首先
新建NewsContentActivity
public class NewsContentActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_content);
String news_title = getIntent().getStringExtra("news_title"); //获取传入的新闻标题
String news_content = getIntent().getStringExtra("news_content");//获取传入的新闻内容
NewsContentFragment newsContentFragment = (NewsContentFragment) getSupportFragmentManager().findFragmentById(R.id.news_content_fragment);
newsContentFragment.refresh(news_title, news_content);
}
/**
* 启动activity并且携带了标题和内容两个参数
*/
public static void actionStart(Context context, String title, String content) {
Intent intent = new Intent(context, NewsContentActivity.class);
intent.putExtra("news_title", title);
intent.putExtra("news_content", content);
context.startActivity(intent);
}
}
在adapter里面启动NewsContentActivity的actionStart方法就可以实现带参跳转。
这个activity的布局就直接使用了新闻详情的fragment,具体代码如下:
新建news_content
<?xml version="1.0" encoding="utf-8"?>
<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:name="com.yiyajing.mypremission.fragment.NewsContentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
这个里面的fragment就是直接复用了双页模式下的NewsContentFragment。
Over