Android实现基本功能的新闻应用
作者:z啵唧啵唧 发布时间:2022-01-07 18:30:06
先准备好一个新闻实体类
package com.zb.fragmentbestpractice
/**
* title:表示新闻的实体类
* content:表示新闻的内容
*/
class News(val title: String, val content: String) {
}
新建布局文件news_content_frag.xml,作为新闻布局的内容
<?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">
<LinearLayout
android:id="@+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="invisible">
<TextView
android:id="@+id/newsTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:textSize="20sp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000000" />
<TextView
android:id="@+id/newsContent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="15dp"
android:textSize="18sp" />
</LinearLayout>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:background="#000000" />
</RelativeLayout>
新闻布局主要分为两个部分:头部部分显示新闻标题,正文部分显示内容,中间使用一条水平方向的细线进行隔开,除此之外还有一条竖直防线的细线,它的作用是在双页模式下将左侧新闻列表和右侧新闻的内容进行分隔开.
我们还需要将新闻内容的布局设置成为不可见,因为在双页模式下,如果还没有选中新闻列表中的任何一条新闻,是不应该显示新闻内容布局的.
接下来新建一个NewsContentFragment类
class NewsContentFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.news_content_frag, container, false)
}
/**
* 该方法用于将新闻的标题和内容显示在我们刚刚定义的界面上,
* 当调用了refresh方法时,需要将我们刚才隐藏的新闻内容布局设置成为可见
*/
fun refresh(title: String, content: String) {
//将布局设置成可见
contentLayout.visibility = View.VISIBLE
//设置新闻标题内容
newsTitle.text = title
//设置新闻内容
newsContent.text = content
}
}
在onCreatView()方法中加载了我们刚刚创建的布局
这样就把新闻内容的Fragment和布局创建好了,但是它们都是在双页模式当中使用的,如果想在单页模式中使用,我们还需要创建一个Activity
创建一个NewsContentActivity
<?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/newsContentFrag"
android:name="com.zb.fragmentbestpractice.NewsContentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
在这个地方发挥了代码的复用性,直接在布局中引入了NewsContentFragment.这样相当于把news_content_frag布局的内容自动加了进来
修改NewsContentActivity中的代码
class NewsContentActivity : AppCompatActivity() {
companion object {
fun actionStart(context: Context, title: String, content: String) {
val intent = Intent(context, NewsContentActivity::class.java).apply {
putExtra("news title", title)
putExtra("news content", content)
}
context.startActivity(intent)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_news_content)
val title = intent.getStringExtra("news title")//获取传入的新闻标题
val content = intent.getStringExtra("news content")//获取传入的新闻内容
if (title != null && content!= null) {
val fragment = newsContentFrag as NewsContentFragment
fragment.refresh(title, content) //刷新NewsContentFragment 界面
}
}
}
onCreate()方法当中,我们通过Intent获取到了传入的新闻标题和新闻内容,然后获取NewsContentFragment实例,接着调用它的refres()方法,将新闻标题和内容传入,就可以把这些数据显示出来了
接下来创建一个用于显示新闻列表的布局,新建news_title_frag.xml
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/newsTitleRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
该布局比较简单,里面只有一个用于显示新闻列表的RecyclerView,既然要用到RecyclerView就要编写子项的布局,新建news_item.xml作为RecyclerView子项的布局
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/newsTitle"
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">
</TextView>
子项布局也比较简单,只有一个TextView
其中android:padding表示给空间周围加上补白,这样不至于让文本内容,紧靠在边缘上
android:ellipsize用于设定当文本内容超出控件宽度时的缩略方式,这里指定成为end表示在尾部进行省略
新闻列表和子布局都创建好了,现在需要一个用于展示新闻列表的地方,这里新建NewsTitleFragment作为列表的Fragment
class NewsTitleFragment : Fragment() {
private var isTwoPane = false
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.news_title_frag, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
isTwoPane = activity?.findViewById<View>(R.id.newsContent.newsContentLayout) != null
}
}
其中的onActivityCreated()方法通过在Activity中能否找到一个id为newsContentLayout的View,来判断当前是双页模式还是单页模式
因此我们需要让这个id为newsContentLayout的View旨在双页模式当中才会出现.
使用限定符实现id为newsContentLayout的View只在双页模式当中才能出现.
修改activity_main.xml中的代码
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/newsTitleLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/newsTitleFrag"
android:name="com.zb.fragmentbestpractice.NewsTitleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
</FrameLayout>
上述代码表示只会在单页模式下加载一个新闻标题的Fragment
然后新建一个layout-sw600dp文件夹,在这个文件夹下面创建一个activity_main.xml文件,代码如下
<?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/newsTitleFrag"
android:name="com.zb.fragmentbestpractice.NewsTitleFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/newsContentLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3">
<fragment
android:id="@+id/newsContentFrag"
android:name="com.zb.fragmentbestpractice.NewsContentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
可以看出在双页模式下面,同时引入了两个fragment,并将新闻内容的fragment放在了Fragment的布局下面,这个Fragment布局id为newsContentFrag
因此只要能够找到这个布局的id就说明是双页模式,反之来说就是单页模式.
接下来就是在NewsTitleFragment中通过RecyclerView将新闻列表展示出来
在NewsTitleFragment中新建一个内部类NewsAdapter,来作为RecyclerView的适配器
package com.zb.fragmentbestpractice
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_news_content.*
import kotlinx.android.synthetic.main.news_item.view.*
import kotlinx.android.synthetic.main.news_title_frag.*
/**
* 用于展示新闻列表
*/
class NewsTitleFragment : Fragment() {
private var isTwoPane = false
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.news_title_frag, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
isTwoPane = activity?.findViewById<View>(R.id.newsContentLayout) != null
val layoutManager = LinearLayoutManager(activity)
newsTitleRecyclerView.layoutManager = layoutManager
val adapter = NewsAdapter(getNews())
newsTitleRecyclerView.adapter = adapter
}
private fun getNews(): List<News> {
val newsList = ArrayList<News>()
for (i in 1..50) {
val news =
News("This is news title $i", getRandomLengthString("This is news content $i."))
newsList.add(news)
}
return newsList
}
private fun getRandomLengthString(str: String): String {
val n = (1..20).random()
val builder = StringBuilder()
repeat(n) {
builder.append(str)
}
return builder.toString()
}
/**
* 内部类,用来作为RecyclerView的适配器
*/
inner class NewsAdapter(val newsList: List<News>) :
RecyclerView.Adapter<NewsAdapter.ViewHolder>() {
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val newsTitle: TextView = view.newsTitle
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view =
LayoutInflater.from(parent.context).inflate(R.layout.news_item, parent, false)
val holder = ViewHolder(view)
holder.itemView.setOnClickListener {
//在newsList当中先获取news实例
val news = newsList[holder.adapterPosition]
//根据isTwoPane判断是单页模式还是双页模式
if (isTwoPane) {
//如果是双页模式,则刷新newsContentFragment中的内容
val fragment = newsContentFrag as NewsContentFragment
fragment.refresh(news.title, news.content)
} else {
//如果是单页模式,则直接启动NewsContentActivity
NewsContentActivity.actionStart(parent.context, news.title, news.content)
}
}
return holder
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val news = newsList[position]
holder.newsTitle.text = news.title
}
override fun getItemCount(): Int {
return newsList.size
}
}
}
最后一步收尾工作,向RecyclerView当中添加数据
修改NewsTitleFragment中的代码
来源:https://blog.csdn.net/weixin_45809829/article/details/128064758


猜你喜欢
- ForkJoinTask就是ForkJoinPool里面的每一个任务。他主要有两个子类:RecursiveAction和RecursiveT
- 背景:最近需要用到人脸识别,但又不花钱使用现有的第三方人脸识别接口,为此使用opencv结合java进行人脸识别(ps:opencv是开源的
- 如何传入字符串参数,分割并遍历如前台传入字符串参数 String str = "a,b,c,d,e,f";现需
- 用户在注册网站信息的时候基本上都要数据验证码验证。那么图片验证码功能该如何实现呢?大概步骤是:1.在内存中创建缓存图片2.设置背景色3.画边
- OO思想现在已经在软件开发项目中广泛应用,其中最重要的一个特性就是继承,最近偶简单的复习了下在C#中涉及到继承这个特性时,所需要用到的关键字
- 主要区别在于是否延迟加载。load方法不会立即访问数据库,当试图加载的记录不存在时,load方法返回一个未初始化的代理对象。get方法总是立
- 前言如今多线程编程已成为了现代软件开发中的重要部分,而并发编程中的线程同步问题更是一道难以逾越的坎。在Java语言中,synchronize
- 一、LinkedHashMap的类继承关系二、源码分析1.自己对LinkedHashMap的理解从继承关系上,我们看到LinkedHashM
- 一、前言在项目中,我们有一些公共的字段需要做修改如:gmt_create:创建时间creator_id:创建人gmt_modified:修改
- 前言最近一段时间看了一些介绍ViewDragHelper的博客,感觉这是一个处理手势滑动的神奇,看完以后就想做点东西练练手,于是就做了这个A
- 上一篇 主要介绍了如何通过蓝牙连接到打印机。这一篇,我们就介绍如何向打印机发送打印指令,来打印字符和图片。1. 构造输出流首先要明确一点,就
- 相关概念1.Handler:可以看做是一个工具类,用来向消息队列中插入消息的;2.Thread:所有与Handler相关的功能都是与Thre
- 1.使用List集合方式用list保存activity实例,然后逐一干掉import java.util.LinkedList;import
- 本文实例讲述了Java编程使用箱式布局管理器。分享给大家供大家参考,具体如下:先来看看运行效果:完整代码如下:package awtDemo
- 目录概述准备工作使用概述springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式
- Android之文件数据存储一、文件保存数据介绍Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的
- 1. IOC和DI首先,我们应该明确,IOC是一种思想,并不是Spring特有的,而是软件工程逐步发展的一种产物,是一种优秀的编程思想,之所
- 在日常开发的过程中我们经常会需要调用第三方组件或者数据库,有的时候可能会因为网络抖动或者下游服务抖动,导致我们某次查询失败。这种时候我们往往
- EntityWrapper的常用方法#WHERE (issue_type = ?) AND (status = ? OR status =
- 静态库和动态库的区别1、静态库的扩展名一般为".a"或者".lib";动态库的扩展名一般为"