基于Android studio的新闻客户端

提醒

我做的Android studio课设,学习了B站博主的内容,敲出来的这个主要的用API连接数据,显示出来,但是每天只能免费使用50次,前期就是搭建框架,再写Java代码,代码里面报错的图片替换成自己找的图标就行,图标可以使用阿里巴巴图标库,获取数据的话用的是聚合数据,搜索新闻,有一个免费的,申请之后到个人中心复制自己的key粘贴到相应的代码处,我在代码中注释了

 下面是这个项目的构成

1、实验目的

掌握 Android 中的菜单及导航框架。

掌握自定义布局。

掌握 Android 中的数据存储。

掌握模块化编程。

掌握网络编程。 

2、总体设计

2.1背景知识

新闻客户端最核心的部分的就是新闻数据,此客户端的数据实现可以采用两种方式搭建数据:静态固定数据和调用API接口,本设计采用Android网络编程,调用API接口来获取新闻数据。

2.2实现步骤:

1、阅读API接口使用文档(调用聚合数据网站的接口)

2、使用 okhttp 获取网络数据

3、使用 gson 将 json 数据转为数据实体类

4、安装 GsonFormatPlus 插件,将数据格式化转为JAVA代码

5、使用 glide 加载网络图片

6、build.gradle下导入相关依赖

3、详细设计

1、数据库设计

1、本APP在设计数据库时需要使用User表还有历史记录表来实现。

用户信息:包括用户的登录信息,这些信息用于用户身份验证

字段名

数据类型

是否可空

说明

username

String

用户名

password

String

密码

nickname

String

昵称

浏览历史记录:包括新闻标题、正文、作者、发布时间、标签、摘要等

字段名

数据类型

是否可空

说明

username

String

用户名

password

String

密码

new_json

String

新闻数据

用户实体图

历史记录实体表

2、数据库的建立

建立两个数据库,user.db用于存储用户信息,history.db用于存储每个用户的历史浏览记录。

3、程序流程图

4、APP前台框架部分

(1)用户登录:如果用户想查看“新闻APP”的内容,首先使用账号和密码进行登录,也可点击记住密码,账号密码验证成功后可进入访问。

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".LoginActivity">
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:title="登录"
        app:titleTextColor="@color/white"
        android:background="@color/purple_200"
        app:navigationIcon="@mipmap/back"/>
    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        android:layout_marginTop="30dp"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/xinwen" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:gravity="center"
        android:text="登录"
        android:textColor="#333"
        android:textSize="20sp"
        android:textStyle="bold" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="26dp"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="@drawable/login_et_bg"
            android:paddingLeft="10dp"
            android:paddingRight="10dp">
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:src="@drawable/yonghu" />
            <EditText
                android:id="@+id/et_username"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="10dp"
                android:background="@null"
                android:hint="请输入用户名"
                android:textSize="14sp" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_marginTop="10dp"
            android:background="@drawable/login_et_bg"
            android:paddingLeft="10dp"
            android:paddingRight="10dp">
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:src="@drawable/mima2" />
            <EditText
                android:id="@+id/et_password"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="10dp"
                android:background="@null"
                android:hint="请输入密码"
                android:inputType="textPassword"
                android:textSize="14sp" />
        </LinearLayout>
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <CheckBox
                android:id="@+id/checkbox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:textColor="@color/purple_200"
                android:text="记住密码" />
            <TextView
                android:id="@+id/register"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginTop="10dp"
                android:text="还未注册?"
                android:textColor="@color/purple_200" />
        </RelativeLayout>
        <Button
            android:id="@+id/login"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_marginTop="20dp"
            android:backgroundTint="@color/purple_200"
            android:text="登录" />
    </LinearLayout>


</LinearLayout>

(2)用户注册:如果用户没有账号和密码,可以点击还未注册通过注册获取账号和密码,输入想要注册的账号和密码后点击注册可完成注册。

activity_register.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".LoginActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:title="注册"
        app:titleTextColor="@color/white"
        android:background="@color/purple_200"
        app:navigationIcon="@mipmap/back"/>
    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        android:layout_marginTop="30dp"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/xinwen" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#333"
        android:textSize="20sp"
        android:textStyle="bold"
        android:layout_margin="20dp"
        android:text="注册"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="26dp"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:background="@drawable/login_et_bg">
            <ImageView
                android:layout_gravity="center_vertical"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/yonghu"/>
            <EditText
                android:id="@+id/et_username"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="10dp"
                android:background="@null"
                android:hint="请输入用户名"
                android:textSize="14sp"/>
        </LinearLayout>

        <LinearLayout
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:background="@drawable/login_et_bg">

            <ImageView
                android:layout_gravity="center_vertical"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/mima2"/>

            <EditText
                android:id="@+id/et_password"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="10dp"
                android:background="@null"
                android:hint="请输入密码"
                android:inputType="textPassword"
                android:textSize="14sp"/>
        </LinearLayout>

        <Button
            android:id="@+id/register"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:backgroundTint="@color/purple_200"
            android:layout_marginTop="20dp"
            android:text="注册"/>
    </LinearLayout>
</LinearLayout>

(3)用户浏览:用户通过账号密码登录成功后可以浏览新闻,用户可以选择推荐、国内、国际、娱乐、体育、军事、科技、财经、游戏、汽车、健康模块进行新闻浏览。

app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:gravity="center_vertical"
        android:background="@color/purple_200">
    <ImageView
            android:id="@+id/btn_open"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/menu"/>
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="40dp">
            <TextView
                android:layout_toLeftOf="@+id/btn_search"
                android:gravity="center_vertical"
                android:background="@color/white"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingLeft="10dp"
                android:hint="热点搜索"/>
            <TextView
                android:id="@+id/btn_search"
                android:layout_alignParentRight="true"
                android:padding="10dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                android:text="搜索"/>
        </RelativeLayout>
    </androidx.appcompat.widget.Toolbar>
    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent">

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            app:tabMode="scrollable"
            app:tabIndicatorFullWidth="false"
            app:tabSelectedTextColor="@color/purple_200"
            app:tabTextColor="#222222"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </androidx.appcompat.widget.LinearLayoutCompat>


</androidx.appcompat.widget.LinearLayoutCompat>

 

(4)用户查看:用户通过选择推荐、国内、国际、娱乐、体育、军事、科技、财经、游戏、汽车、健康这十一个模块进行新闻查看,若遇到感兴趣的标题可以点进去查看全文。

(5)侧边栏:点击右上角三条杠可以显示侧边栏内容

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        android:id="@+id/app_bar_main"
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:itemTextColor="#666666"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>

(6)侧边栏历史记录框架

activity_history_list.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".HistoryListActivity">


    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        app:navigationIcon="@drawable/back2"
        app:title="浏览历史"
        app:titleTextColor="@color/white"
        android:background="@color/purple_200"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        tools:listitem="@layout/news_list_item"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</androidx.appcompat.widget.LinearLayoutCompat>

(7)修改密码

activity_update_pwd.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".UpdatePwdActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/purple_200"
        app:navigationIcon="@mipmap/back"
        app:title="修改密码"
        app:titleTextColor="@color/white"/>

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="26dp"
        android:layout_marginRight="26dp"
        android:layout_marginTop="50dp">
        <androidx.appcompat.widget.LinearLayoutCompat
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:background="@drawable/login_et_bg"
            android:layout_width="match_parent"
            android:layout_height="50dp">
            <ImageView
                android:layout_gravity="center_vertical"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/mima2"/>
            <EditText
                android:id="@+id/et_new_password"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:textSize="14sp"
                android:background="@null"
                android:paddingLeft="10dp"
                android:inputType="textPassword"
                android:hint="请输入新密码"/>
        </androidx.appcompat.widget.LinearLayoutCompat>

    </androidx.appcompat.widget.LinearLayoutCompat>

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="26dp"
        android:layout_marginRight="26dp"
        android:layout_marginTop="5dp">
        <androidx.appcompat.widget.LinearLayoutCompat
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:background="@drawable/login_et_bg"
            android:layout_width="match_parent"
            android:layout_height="50dp">
            <ImageView
                android:layout_gravity="center_vertical"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/mima2"/>
            <EditText
                android:id="@+id/et_confirm_password"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:textSize="14sp"
                android:background="@null"
                android:paddingLeft="10dp"
                android:hint="请输入确认的新密码"
                android:inputType="textPassword"/>
        </androidx.appcompat.widget.LinearLayoutCompat>

        <Button
            android:id="@+id/btn_update_pwd"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:backgroundTint="@color/purple_200"
            android:text="修改密码"/>
    </androidx.appcompat.widget.LinearLayoutCompat>

</LinearLayout>

5、项目开发过程

5.1 APP功能模块

5.1.1 用户登录功能:用户通过账号密码登录成功后可以进入系统内访问或者阅读当前新闻内容。

package cn.itcast.android_new;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;


import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;


import cn.itcast.android_new.db.UserDbHelper;
import cn.itcast.android_new.entity.UserInfo;

public class LoginActivity extends AppCompatActivity {
    private EditText et_username;
    private EditText et_password;
    private SharedPreferences mSharedPreferences;
    private CheckBox checkBox;
    private boolean is_login;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        //获取mSharedPreferences
        mSharedPreferences=getSharedPreferences("user",MODE_PRIVATE);
        //初始化控件
        et_username=findViewById(R.id.et_username);
        et_password=findViewById(R.id.et_password);
        checkBox=findViewById(R.id.checkbox);
        //是否勾选记住了密码
        is_login=mSharedPreferences.getBoolean("is_login",false);
        if (is_login){
            String username=mSharedPreferences.getString("username",null);
            String password=mSharedPreferences.getString("password",null);
            et_username.setText(username);
            et_password.setText(password);
            checkBox.setChecked(true);
        }
        //点击注册
        findViewById(R.id.register).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到注册页面
                Intent intent=new Intent(LoginActivity.this,RegisterActivity.class);
                startActivity(intent);
            }
        });
        //登录返回
        findViewById(R.id.toolbar).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        //登录
        findViewById(R.id.login).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String username=et_username.getText().toString();
                String password=et_password.getText().toString();
                if (TextUtils.isEmpty(username)||TextUtils.isEmpty(password)){
                    Toast.makeText(LoginActivity.this, "请输入用户名或密码", Toast.LENGTH_SHORT).show();
                }else {
                    UserInfo login= UserDbHelper.getInstance(LoginActivity.this).login(username);
                    if (login!=null){
                        if (username.equals(login.getUsername())&&password.equals(login.getPassword())){
                            SharedPreferences.Editor edit=mSharedPreferences.edit();
                            edit.putBoolean("is_login",is_login);
                            edit.putString("username",username);
                            edit.putString("password",password);
                            edit.commit();
                            //保存用户名和密码
                            UserInfo.setsUserInfo(login);
                            Intent intent=new Intent(LoginActivity.this,MainActivity.class);
                            startActivity(intent);
                            finish();
                        }else {
                            Toast.makeText(LoginActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
                        }
                    }else {
                        Toast.makeText(LoginActivity.this, "该用户暂未注册", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });
        //checkbox的点击事件
        checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
            @Override
            public void onCheckedChanged(CompoundButton buttonView,boolean isChecked){
                is_login=isChecked;
            }
        });
    }
}

2.1.2 用户注册功能:如果用户没有访问该系统的权限,可以通过注册功能注册用户账号密码,注册成功后跳转登陆页面。

package cn.itcast.android_new;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.camera2.TotalCaptureResult;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import cn.itcast.android_new.db.UserDbHelper;


public class RegisterActivity extends AppCompatActivity {

    private EditText et_username;
    private EditText et_password;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);

        //初始化控件
        et_username=findViewById(R.id.et_username);
        et_password=findViewById(R.id.et_password);

        //返回登录界面
        findViewById(R.id.toolbar).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        //点击注册
        findViewById(R.id.register).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String username=et_username.getText().toString();
                String password=et_password.getText().toString();
                if(TextUtils.isEmpty(username)||TextUtils.isEmpty(password)){
                    Toast.makeText(RegisterActivity.this, "请输入用户名或密码", Toast.LENGTH_SHORT).show();
                }else{
                    int row= UserDbHelper.getInstance(RegisterActivity.this).register(username,password,"暂无~~");
                    if (row>=0){
                        Toast.makeText(RegisterActivity.this, "注册成功,请登录", Toast.LENGTH_SHORT).show();
                        finish();
                    }

                }
            }
        });
    }
}

2.1.3页面浏览功能:用户注册并登录成功后,可以进入系统浏览推荐、国内、国际、娱乐、体育、军事、科技、财经、游戏、汽车、健康这十一个模块新闻页面。

package cn.itcast.android_new;

import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.google.gson.Gson;

import java.io.IOException;

import cn.itcast.android_new.adapter.NewsListAdapter;
import cn.itcast.android_new.entity.NewsInfo;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class TabNewsFragment extends Fragment {
//这里的key可以在聚合数据里面搜索新闻有一个免费的数据,申请通过后在个人中心复制自己的key,不要直接复制别人的每天只能免费使用50次
    private String url="http://v.juhe.cn/toutiao/index?key=7877298928877uygb12446type=";
    private View rootView;
    private RecyclerView recyclerView;
    private NewsListAdapter mNewsListAdapter;
    private static final String ARG_PARAM = "title";
    private String title;
    private Handler mHandler=new Handler(Looper.myLooper()) {

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what==100){
                String data= (String) msg.obj;
                NewsInfo newsInfo = new Gson().fromJson(data, NewsInfo.class);
                if (newsInfo!=null&&newsInfo.getError_code()==0){
                    //逻辑处理
                    if (null!=mNewsListAdapter){
                        mNewsListAdapter.setListData(newsInfo.getResult().getData());
                    }
                }else {
                    Toast.makeText(getActivity(), "获取数据失败,请稍后重试", Toast.LENGTH_SHORT).show();
                }

            }
        }
    };


    public TabNewsFragment() {
        // Required empty public constructor
    }

    public static TabNewsFragment newInstance(String param) {
        TabNewsFragment fragment = new TabNewsFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM, param);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            title = getArguments().getString(ARG_PARAM);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        rootView=inflater.inflate(R.layout.fragment_tab_news, container, false);

        //初始化控件
        recyclerView=rootView.findViewById(R.id.recyclerView);
        return rootView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        //初始化适配器
        mNewsListAdapter=new NewsListAdapter(getActivity());

        //设置adapter
        recyclerView.setAdapter(mNewsListAdapter);

        //recyclerView列表点击事件
        mNewsListAdapter.setmOnItemClickListener(new NewsListAdapter.onItemClickListener() {
            @Override
            public void onItemClick(NewsInfo.ResultDTO.DataDTO dataDTO, int position) {
                //跳转到详情页
                Intent intent=new Intent(getActivity(),NewsDetailsActivity.class);
                //传递对象的时候,该类一定要实现Serializable
                intent.putExtra("dataDTO",dataDTO);
                startActivity(intent);
            }
        });

        //获取数据
        getHttpData();
    }

    private void getHttpData() {

        //创建OkHttpClient对象
        OkHttpClient okHttpClient=new OkHttpClient();
        //构构造Request对象
        Request request = new Request.Builder()
                .url(url+title)
                .get()
                .build();

        //通过OkHttpClient和Request对象来构建Call对象
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {

                Log.d("----------------","onFailure:"+e.toString());
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                String data = response.body().string();
                Log.d("--------------","onResponse:"+data);

                //不能在耗时操作中更新UI,需要使用handler
                Message message=new Message();
                message.what=100;
                message.obj=data;
                //发送
                mHandler.sendMessage(message);

            }
        });
    }
}

2.1.4 新闻查看功能:如果用户发现非常感兴趣的新闻标题或图片,可以点击该新闻进入详情页面进行阅读。

package cn.itcast.android_new;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;

import com.google.gson.Gson;

import cn.itcast.android_new.db.HistoryDbHelper;
import cn.itcast.android_new.entity.NewsInfo;

public class NewsDetailsActivity extends AppCompatActivity {
    private NewsInfo.ResultDTO.DataDTO dataDTO;
    private Toolbar toolbar;
    private WebView mWebView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_news_details);

        //初始化控件
        toolbar=findViewById(R.id.toolbar);
        mWebView=findViewById(R.id.webView);
        //获取传递的数据
        dataDTO= (NewsInfo.ResultDTO.DataDTO) getIntent().getSerializableExtra("dataDTO");

        //设置数据
        if (null!=dataDTO){
            toolbar.setTitle(dataDTO.getTitle());
            mWebView.loadUrl(dataDTO.getUrl());

            //添加历史记录
            String dataDTOJson = new Gson().toJson(dataDTO);
            HistoryDbHelper.getInstance(NewsDetailsActivity.this).addHistory(null,dataDTO.getUniquekey(),dataDTOJson);
        }
        //返回
        toolbar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

    }

}

2.1.5查看历史记录模块:点击侧边栏,可以加入,点击历史记录可以查看历史记录

 

package cn.itcast.android_new.db;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

import cn.itcast.android_new.entity.HistoryInfo;

public class HistoryDbHelper extends SQLiteOpenHelper {
    private static HistoryDbHelper sHelper;
    private static final String DB_NAME = "history.db";   //数据库名
    private static final int VERSION = 1;    //版本号

    //必须实现其中一个构方法
    public HistoryDbHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }
    //创建单例,供使用调用该类里面的的增删改查的方法
    public synchronized static HistoryDbHelper getInstance(Context context) {
        if (null == sHelper) {
            sHelper = new HistoryDbHelper(context, DB_NAME, null, VERSION);
        }
        return sHelper;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建history_table表
        db.execSQL("create table history_table(history_id integer primary key autoincrement, " +
                "username text," +       //用户名
                "uniquekey text," +      //新闻id
                "new_json text" +       // 新闻数据
                ")");


    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }

    //添加历史记录
    public int addHistory(String username, String uniquekey, String new_json) {

        //判断是否浏览过历史记录
        if(!isHistory(uniquekey)){
            //获取SQLiteDatabase实例
            SQLiteDatabase db = getWritableDatabase();
            ContentValues values = new ContentValues();
            //填充占位符
            values.put("username", username);
            values.put("uniquekey", uniquekey);
            values.put("new_json", new_json);
            String nullColumnHack = "values(null,?,?,?)";
            //执行
            int insert = (int) db.insert("history_table", nullColumnHack, values);
            db.close();
            return insert;
        }
        return 0;
    }

    //判断是否浏览过历史记录
    @SuppressLint("Range")
    public boolean isHistory(String uniquekey) {
        //获取SQLiteDatabase实例
        SQLiteDatabase db = getReadableDatabase();
        String sql = "select history_id,username,uniquekey,new_json  from history_table where uniquekey=?";
        String[] selectionArgs = {uniquekey};
        Cursor cursor = db.rawQuery(sql, selectionArgs);
//        cursor.close();
//        db.close();
        return cursor.moveToNext();
    }

    /**
     * 获取所有历史记录
     */
    @SuppressLint("Range")
    public List<HistoryInfo> queryHistoryListData(String username) {
        //获取SQLiteDatabase实例
        SQLiteDatabase db = getReadableDatabase();
        List<HistoryInfo> list = new ArrayList<>();
        String sql;
        Cursor cursor;
        if (username==null){
            sql = "select history_id,username,uniquekey,new_json  from history_table";
            cursor = db.rawQuery(sql, null);
        }else {
            sql = "select history_id,username,uniquekey,new_json  from history_table where username=?";
            cursor = db.rawQuery(sql, new String[]{username});
        }

        while (cursor.moveToNext()) {
            int history_id = cursor.getInt(cursor.getColumnIndex("history_id"));
            String userName = cursor.getString(cursor.getColumnIndex("username"));
            String uniquekey = cursor.getString(cursor.getColumnIndex("uniquekey"));
            String new_json = cursor.getString(cursor.getColumnIndex("new_json"));
            list.add(new HistoryInfo(history_id, userName, uniquekey, new_json));
        }
        cursor.close();
        db.close();
        return list;
    }

}

2.1.6用户退出界面模块:点击侧边栏退出登录,直接退出返回登录界面 

   

2.1.7修改密码

package cn.itcast.android_new;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import cn.itcast.android_new.db.UserDbHelper;
import cn.itcast.android_new.entity.UserInfo;


public class UpdatePwdActivity extends AppCompatActivity {
    private EditText et_new_password;
    private EditText et_confirm_password;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_update_pwd);

        //初始化控件
        et_new_password=findViewById(R.id.et_new_password);
        et_confirm_password=findViewById(R.id.et_confirm_password);

        //修改密码点击事件
        findViewById(R.id.btn_update_pwd).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String new_pwd=et_new_password.getText().toString();
                String confirm_pwd=et_confirm_password.getText().toString();
                if(TextUtils.isEmpty(new_pwd)||TextUtils.isEmpty(confirm_pwd)){
                    Toast.makeText(UpdatePwdActivity.this, "密码不能为空", Toast.LENGTH_SHORT).show();

                }else if (!new_pwd.equals(confirm_pwd)){
                    Toast.makeText(UpdatePwdActivity.this, "新密码与确认密码不一致", Toast.LENGTH_SHORT).show();

                }else {
                    UserInfo userInfo=UserInfo.getsUserInfo();
                    if (null!=userInfo){
                        int row= UserDbHelper.getInstance(UpdatePwdActivity.this).updatePwd(userInfo.getUsername(),new_pwd);
                        if (row>0){
                            Toast.makeText(UpdatePwdActivity.this, "密码修改成功,请重新登录", Toast.LENGTH_SHORT).show();
//                            setResult(1000);
                            startActivity(new Intent(UpdatePwdActivity.this,LoginActivity.class));
                            UserInfo.setsUserInfo(null);
                            finish();
                        }else {
                            Toast.makeText(UpdatePwdActivity.this, "密码修改失败", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            }
        });
        //返回 视频的方法不对 不能直接用finish()关闭,从Activity跳转到fragment方法要复杂一些
//        findViewById(R.id.toolbar).setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                finish();
//                Intent intent=new Intent(UpdatePwdActivity.this,RegisterActivity.class);
//                startActivity(intent);
//            }
//        });
        findViewById(R.id.toolbar2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }
}
  • 51
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
好的,以下是实现新闻列表展示界面和增删改查的具体代码。 1. 首先在布局文件中定义一个 RecyclerView 来展示新闻列表。 ``` <androidx.recyclerview.widget.RecyclerView android:id="@+id/newsListRecyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" /> ``` 2. 在 Java 文件中定义一个 NewsAdapter 继承 RecyclerView.Adapter,并实现其相关方法。 ``` public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> { private List<News> mNewsList; static class ViewHolder extends RecyclerView.ViewHolder { TextView newsTitleText; public ViewHolder(View view) { super(view); newsTitleText = view.findViewById(R.id.newsTitleText); } } public NewsAdapter(List<News> newsList) { mNewsList = newsList; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, false); ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { News news = mNewsList.get(position); holder.newsTitleText.setText(news.getTitle()); } @Override public int getItemCount() { return mNewsList.size(); } } ``` 3. 在 MainActivity 中初始化 RecyclerView,并设置其 Adapter 和 LayoutManager。 ``` public class MainActivity extends AppCompatActivity { private List<News> mNewsList = new ArrayList<>(); private NewsAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initNews(); RecyclerView newsListRecyclerView = findViewById(R.id.newsListRecyclerView); LinearLayoutManager layoutManager = new LinearLayoutManager(this); newsListRecyclerView.setLayoutManager(layoutManager); mAdapter = new NewsAdapter(mNewsList); newsListRecyclerView.setAdapter(mAdapter); } private void initNews() { // TODO: 初始化新闻列表数据 } } ``` 4. 实现增删改查操作,以下是具体代码。 ``` public class MainActivity extends AppCompatActivity { private List<News> mNewsList = new ArrayList<>(); private NewsAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initNews(); RecyclerView newsListRecyclerView = findViewById(R.id.newsListRecyclerView); LinearLayoutManager layoutManager = new LinearLayoutManager(this); newsListRecyclerView.setLayoutManager(layoutManager); mAdapter = new NewsAdapter(mNewsList); newsListRecyclerView.setAdapter(mAdapter); // 添加新闻 FloatingActionButton addNewsButton = findViewById(R.id.addNewsButton); addNewsButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO: 弹出添加新闻对话框 // 添加新闻到 mNewsList 中 mAdapter.notifyDataSetChanged(); } }); // 删除新闻 ItemTouchHelper.Callback callback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { @Override public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { return false; } @Override public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { int position = viewHolder.getAdapterPosition(); mNewsList.remove(position); mAdapter.notifyItemRemoved(position); } }; ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback); itemTouchHelper.attachToRecyclerView(newsListRecyclerView); // 修改新闻 mAdapter.setOnItemClickListener(new NewsAdapter.OnItemClickListener() { @Override public void onItemClick(View view, int position) { // TODO: 弹出修改新闻对话框 // 更新 mNewsList 中对应位置的新闻 mAdapter.notifyItemChanged(position); } }); // 查询新闻 SearchView searchView = findViewById(R.id.searchView); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { // TODO: 根据关键字查询新闻列表 // 更新 mNewsList 中的数据 mAdapter.notifyDataSetChanged(); return false; } @Override public boolean onQueryTextChange(String newText) { return false; } }); } private void initNews() { // TODO: 初始化新闻列表数据 } } ``` 以上是 Android Studio 实现新闻列表展示界面和增删改查的具体代码,其中的 TODO 部分需要根据具体需求进行实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值