Android实现基本功能的新闻应用

2022-12-02 21:47:28

先准备好一个新闻实体类

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中的代码

                    到此这篇关于Android实现基本功能的新闻应用的文章就介绍到这了,更多相关Android新闻应用内容请搜索易采站长站以前的文章或继续浏览下面的相关文章希望大家以后多多支持易采站长站!