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

标签:Android,新闻
0
投稿

猜你喜欢

  • Java程序中实现调用Python脚本的方法详解

    2021-07-08 22:00:08
  • C#中CheckedListBox控件的用法实例

    2021-08-05 06:03:29
  • 有关Java中的BeanInfo介绍

    2023-08-05 00:13:42
  • Android实现截图和分享功能的代码

    2023-04-09 22:56:43
  • java 工厂模式的讲解及优缺点的介绍

    2022-02-05 10:57:09
  • C#和JavaScript实现交互的方法

    2022-05-24 02:10:40
  • 为什么mybatis中的SqlSession一定要关闭

    2022-02-24 07:57:11
  • java使用链表实现约瑟夫环

    2022-03-21 18:59:35
  • Android之沉浸式状态栏的实现方法、状态栏透明

    2022-01-02 17:49:21
  • SpringBoot 整合jdbc和mybatis的方法

    2023-08-10 12:51:09
  • Android之Viewpager+Fragment实现懒加载示例

    2021-06-30 04:36:20
  • 详述 DB2 分页查询及 Java 实现的示例

    2023-04-21 12:39:12
  • java实现PDF转图片的方法

    2021-05-24 04:29:59
  • Android WebView 常见问题及处理方案

    2023-04-13 04:11:57
  • SpringBoot集成支付宝沙箱支付的实现示例

    2023-10-31 19:22:20
  • C#常见的几种集合 ArrayList,Hashtable,List<T>,Dictionary<K,V> 遍历方法对比

    2021-07-25 17:00:04
  • java中List分页的几种方法介绍

    2022-03-01 12:04:28
  • 关于c#中单例模式的一些问题

    2022-01-21 08:56:18
  • Springboot如何使用mybatis实现拦截SQL分页

    2021-08-15 13:16:56
  • 详解JAVA类加载机制

    2023-11-08 04:05:16
  • asp之家 软件编程 m.aspxhome.com