Android安卓毕业设计实战项目(21)新闻app(分类:社会、军事、科技、财经、娱乐)【可用于安卓毕设或安卓课设作业】(源码见文末)

一.项目运行介绍


视频演示地址:https://www.bilibili.com/video/BV1Ju4y1x75p/


image-20231005171527290

二.具体实现

package com.llw.goodnews.ui.activity

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.google.accompanist.navigation.animation.composable
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
import com.llw.goodnews.ui.pages.EpidemicNewsListPage
import com.llw.goodnews.ui.pages.HomePage
import com.llw.goodnews.ui.pages.PageConstant.EPIDEMIC_NEWS_LIST_PAGE
import com.llw.goodnews.ui.pages.PageConstant.HOME_PAGE
import com.llw.goodnews.ui.pages.PageConstant.RISK_ZONE_DETAILS_PAGE
import com.llw.goodnews.ui.pages.PageConstant.WEB_VIEW_PAGE
import com.llw.goodnews.ui.pages.RiskZoneDetailsPage
import com.llw.goodnews.ui.pages.WebViewPage
import com.llw.goodnews.ui.theme.GoodNewsTheme
import com.llw.goodnews.viewmodel.HomeViewModel
import com.llw.goodnews.viewmodel.MainViewModel
import dagger.hilt.android.AndroidEntryPoint

/**
 * 主页面
 */
@AndroidEntryPoint
class HomeActivity : ComponentActivity() {

    @ExperimentalAnimationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            GoodNewsTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    val viewModel: MainViewModel = viewModel()
                    val homeViewModel: HomeViewModel = viewModel()
                    val navController = rememberAnimatedNavController()
                    AnimatedNavHost(
                        navController = navController,
                        startDestination = HOME_PAGE,
                        //进入动画
                        enterTransition = {
                            slideInHorizontally(
                                initialOffsetX = { fullWidth -> fullWidth },
                                animationSpec = tween(500)
                            )
                        },
                        //退出动画
                        exitTransition = {
                            slideOutHorizontally(
                                targetOffsetX = { fullWidth -> -fullWidth },
                                animationSpec = tween(500)
                            )
                        },
                        popEnterTransition = {
                            slideInHorizontally(
                                initialOffsetX = { fullWidth -> -fullWidth },
                                animationSpec = tween(500)
                            )
                        },
                        popExitTransition = {
                            slideOutHorizontally(
                                targetOffsetX = { fullWidth -> fullWidth },
                                animationSpec = tween(500)
                            )
                        }
                    ) {
                        //主页面
                        composable(HOME_PAGE) {
                            HomePage(navController,homeViewModel)
                        }
                        //疫情新闻列表页面
                        composable(EPIDEMIC_NEWS_LIST_PAGE) {
                            EpidemicNewsListPage(navController, viewModel)
                        }
                        //风险区详情页面
                        composable(
                            "$RISK_ZONE_DETAILS_PAGE/{title}/{stringList}",
                            arguments = listOf(
                                navArgument("title") {
                                    type = NavType.StringType //数据类型
                                },
                                navArgument("stringList") {
                                    type = NavType.StringType
                                }
                            )
                        ) {
                            val title = it.arguments?.getString("title") ?: "风险区详情"
                            val stringList = it.arguments?.getString("stringList")
                            RiskZoneDetailsPage(navController, title, stringList)
                        }
                        //WebView页面
                        composable(
                            "$WEB_VIEW_PAGE/{title}/{url}",
                            arguments = listOf(
                                navArgument("title") {
                                    type = NavType.StringType
                                },
                                navArgument("url") {
                                    type = NavType.StringType
                                },
                            )
                        ) {
                            val title = it.arguments?.getString("title") ?: "WebView页面"
                            val url = it.arguments?.getString("url") ?: "WebViewUrl"
                            WebViewPage(navController, title, url)
                        }
                    }
                }
            }
        }
    }
}

这是一个使用Jetpack Compose库和与Compose集成的Navigation Component构建的Android应用程序的Kotlin代码段。它代表了一个名为"HomeActivity"的应用程序的主活动。让我们逐步解释这段代码:

  1. 导入语句:

    • 代码以各种导入语句开始,这些语句引入了使用Jetpack Compose和Navigation Component构建Android应用程序所需的类和包。
  2. 类声明:

    • HomeActivity 被声明为一个类,它扩展了 ComponentActivity,这是Android活动框架的一部分。
  3. @AndroidEntryPoint 注解:

    • 此注解用于指示此活动是Hilt依赖注入系统的一部分。Hilt是用于Android上的依赖注入的库。
  4. onCreate 函数:

    • onCreate 函数是此活动的入口点,并在创建活动时调用。
  5. setContent 函数:

    • onCreate 函数内,使用 setContent 函数设置了活动的内容为Compose UI。
  6. Compose UI 内容:

    • Compose UI 在 GoodNewsTheme 可组合函数内定义。
    • 使用 Surface 可组合函数提供了基于 MaterialTheme 的背景颜色。它占据整个屏幕(使用 fillMaxSize())。
    • 创建了 MainViewModelHomeViewModel 的 ViewModel 实例(使用 viewModel())。
    • 使用 rememberAnimatedNavController 创建支持在目标之间执行动画过渡的导航控制器。
  7. AnimatedNavHost 可组合函数:

    • AnimatedNavHost 是一个用于Compose应用程序中的导航的可组合函数。它类似于标准的 NavHost,但支持自定义导航过渡的动画。
    • startDestination 设置为 HOME_PAGE,表示初始目标。
    • 使用 slideInHorizontallyslideOutHorizontally 为进入、退出、弹出进入和弹出退出过渡指定了各种动画过渡。
  8. 可组合目标:

    • AnimatedNavHost 内,使用 composable 函数为不同的应用程序页面定义了不同的可组合目标。
    • HOME_PAGE:用于主页面的可组合函数。
    • EPIDEMIC_NEWS_LIST_PAGE:用于疫情新闻列表的可组合函数。
    • RISK_ZONE_DETAILS_PAGE:用于风险区域详情页面的可组合函数,接受参数如 “title” 和 “stringList”。
    • WEB_VIEW_PAGE:用于Web视图页面的可组合函数,还接受 “title” 和 “url” 作为参数。

总的来说,这段代码为使用Jetpack Compose构建的Android应用程序设置了导航结构,定义了不同的页面或目标,并指定了它们之间的动画过渡。它还与Hilt集成,用于依赖注入。

package com.llw.goodnews.repository

import com.llw.goodnews.App
import com.llw.goodnews.db.bean.CollectionNews
import com.llw.goodnews.db.bean.News
import com.llw.goodnews.network.NetworkRequest
import com.llw.goodnews.utils.Constant.CODE
import dagger.hilt.android.scopes.ViewModelScoped
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject

/**
 * 新闻数据
 * @description HomeRepository
 * @author llw
 */
@ViewModelScoped
class HomeRepository @Inject constructor() : BaseRepository() {

    /**
     * 获取社会新闻
     */
    fun getSocialNews() = fire(Dispatchers.IO) {
        val news = NetworkRequest.getSocialNews()
        if (news.code == CODE) Result.success(news)
        else Result.failure(RuntimeException("getNews response code is ${news.code} msg is ${news.msg}"))
    }

    /**
     * 获取军事新闻
     */
    fun getMilitaryNews() = fire(Dispatchers.IO) {
        val news = NetworkRequest.getMilitaryNews()
        if (news.code == CODE) Result.success(news)
        else Result.failure(RuntimeException("getNews response code is ${news.code} msg is ${news.msg}"))
    }

    /**
     * 科技新闻
     */
    fun getTechnologyNews() = fire(Dispatchers.IO) {
        val news = NetworkRequest.getTechnologyNews()
        if (news.code == CODE) Result.success(news)
        else Result.failure(RuntimeException("getNews response code is ${news.code} msg is ${news.msg}"))
    }

    /**
     * 财经新闻
     */
    fun getFinanceNews() = fire(Dispatchers.IO) {
        val news = NetworkRequest.getFinanceNews()
        if (news.code == CODE) Result.success(news)
        else Result.failure(RuntimeException("getNews response code is ${news.code} msg is ${news.msg}"))
    }

    /**
     * 娱乐新闻
     */
    fun getAmusementNews() = fire(Dispatchers.IO) {
        val news = NetworkRequest.getAmusementNews()
        if (news.code == CODE) Result.success(news)
        else Result.failure(RuntimeException("getNews response code is ${news.code} msg is ${news.msg}"))
    }

    /**
     * 获取收藏新闻
     */
    fun getCollectionNews() = fire(Dispatchers.IO) {
        val collectionNews = App.db.collectionNewsDao().getCollectionNews()
        if (collectionNews.isNotEmpty()) Result.success(collectionNews)
        else Result.failure(RuntimeException("getCollectionNews response is null"))
    }

    /**
     * 保存新闻数据
     */
    private suspend fun insertCollectionNew(collectionNews: CollectionNews) =
        App.db.collectionNewsDao().insert(collectionNews)

    /**
     * 删除新闻数据
     */
    private suspend fun deleteCollectionNew(collectionNews: CollectionNews) =
        App.db.collectionNewsDao().delete(collectionNews)
}

这是一个用于处理新闻数据的Kotlin类,它似乎是一个用于新闻应用程序的存储库(Repository)。让我解释一下这个代码的主要部分:

  1. 导入语句:

    • 代码开始以导入所需的类和包的语句。这些导入语句用于引入依赖项,包括数据库操作、网络请求以及其他辅助类。
  2. HomeRepository 类声明:

    • HomeRepository 类是一个ViewModel作用域的类,它使用了Hilt的 @ViewModelScoped 注解。
    • 它是一个依赖注入的类,使用了 @Inject 注解,这表示它可以被依赖注入框架(如Hilt)实例化。
  3. 函数定义:

    • 这个类包含了多个用于获取不同类型新闻的函数,例如社会新闻、军事新闻、科技新闻、财经新闻和娱乐新闻。
    • 每个函数都使用 fire 函数来执行异步操作,并且这些操作在IO调度器(Dispatchers.IO)上运行。这些函数通过调用 NetworkRequest 的相关方法来获取新闻数据,并根据特定的条件返回一个 Result 对象。
    • 如果获取的新闻数据的响应代码(code)等于指定的 Constant.CODE,则返回成功的 Result.success(news);否则,返回一个包含异常信息的失败的 Result 对象。
  4. 获取收藏新闻:

    • getCollectionNews 函数用于从本地数据库获取已收藏的新闻数据。
    • 它通过调用数据库访问对象(collectionNewsDao)的 getCollectionNews 方法来获取收藏的新闻数据,并将其封装在 Result 中返回。
  5. 保存和删除新闻数据:

    • 有两个私有挂起函数 insertCollectionNewdeleteCollectionNew 用于在本地数据库中保存和删除新闻数据。
    • insertCollectionNew 将给定的 CollectionNews 对象插入到数据库中。
    • deleteCollectionNew 从数据库中删除给定的 CollectionNews 对象。

总的来说,这个类充当了新闻数据的中间层,负责从网络请求或本地数据库中获取新闻数据,并提供接口来执行与新闻相关的操作,如获取不同类型的新闻、获取收藏的新闻、保存和删除新闻数据。这有助于将数据访问和业务逻辑分离,使应用程序更具可维护性。



三.项目源码

链接:https://pan.baidu.com/s/1JjpTLtw3_5iwRbmSGtOP7w?pwd=nljy
提取码:nljy

注:项目已加密,请联系作者V

(可做实验报告,代码讲解等…)

请私信作者或

(v)15135757306


猜你喜欢

转载自blog.csdn.net/m0_63324772/article/details/133581702