网易新闻APP

文章目录

        • 界面设计
        • 网易新闻列表
          • 使用bejson网站的Json转实体类生产JsonRootBean和Result类型
          • 新闻单行的布局文件news_item.xml
          • 适配器NewsAdapter
          • 主界面的布局文件
          • 主界面Java文件
        • MyUser的类定义文件
        • Comment表的类定义文件
        • Favorite表的类定义文件
        • 查看新闻详情页面的布局文件
        • 查看新闻详情的Java文件

界面设计

1、网易新闻列表
2.、网易新闻详情
3、评论列表
4、我的收藏

网易新闻列表

网址 :https://api.apiopen.top/getWangYiNews
网易新闻APP_第1张图片

使用bejson网站的Json转实体类生产JsonRootBean和Result类型

网易新闻APP_第2张图片

JsonRootBean

/**
  * Copyright 2021 bejson.com 
  */
package com.example.demo;
import java.util.List;

/**
 * Auto-generated: 2021-05-12 11:3:57
 *
 * @author bejson.com ([email protected])
 * @website http://www.bejson.com/java2pojo/
 */
public class JsonRootBean {
     

    private int code;
    private String message;
    private List<Result> result;
    public void setCode(int code) {
     
         this.code = code;
     }
     public int getCode() {
     
         return code;
     }

    public void setMessage(String message) {
     
         this.message = message;
     }
     public String getMessage() {
     
         return message;
     }

    public void setResult(List<Result> result) {
     
         this.result = result;
     }
     public List<Result> getResult() {
     
         return result;
     }

}

Result

/**
 * Copyright 2021 bejson.com
 */
package com.example.demo;

import java.util.Date;

/**
 * Auto-generated: 2021-05-12 11:3:57
 *
 * @author bejson.com ([email protected])
 * @website http://www.bejson.com/java2pojo/
 */
public class Result {
     

    private String path;
    private String image;
    private String title;
    private String passtime;

    public void setPath(String path) {
     
        this.path = path;
    }

    public String getPath() {
     
        return path;
    }

    public void setImage(String image) {
     
        this.image = image;
    }

    public String getImage() {
     
        return image;
    }

    public void setTitle(String title) {
     
        this.title = title;
    }

    public String getTitle() {
     
        return title;
    }

    public void setPasstime(String passtime) {
     
        this.passtime = passtime;
    }

    public String getPasstime() {
     
        return passtime;
    }

}
新闻单行的布局文件news_item.xml

<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="60dp"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/iv_news"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:padding="5dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="20dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="新闻标题" />

        <TextView
            android:id="@+id/tv_time"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="新闻时间" />


    LinearLayout>


LinearLayout>
适配器NewsAdapter
package com.example.demo;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

public class NewsAdapter extends BaseAdapter {
     
    private Context context;
    private List<Result> resultList;

    public NewsAdapter(Context context, List<Result> resultList) {
     
        this.context = context;
        this.resultList = resultList;
    }

    @Override
    public int getCount() {
     
        return resultList.size();
    }

    @Override
    public Object getItem(int position) {
     
        return resultList.get(position);
    }

    @Override
    public long getItemId(int position) {
     
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
     
        if (convertView == null) {
     
            convertView = LayoutInflater.from(context).inflate(
                    R.layout.news_item, parent, false);
        }

        // 新闻图片 标题  时间
        ImageView iv_news = convertView.findViewById(R.id.iv_news);
        TextView tv_title = convertView.findViewById(R.id.tv_title);
        TextView tv_time = convertView.findViewById(R.id.tv_time);

        Result result = resultList.get(position);

        tv_title.setText(result.getTitle());
        tv_time.setText(result.getPasstime());

        // 加载图片
        try {
     
            URL url = new URL(result.getImage());
            Glide.with(context).load(url).into(iv_news);
        } catch (MalformedURLException e) {
     
            e.printStackTrace();
        }

      return convertView;
    }

    public void changeData(List<Result> resultList) {
     
        this.resultList = resultList;
        notifyDataSetChanged();
    }
}


主界面的布局文件

<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"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lv_duanzi"/>

LinearLayout>
主界面Java文件
package com.example.demo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

import com.google.gson.Gson;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {
     
    private static final String TAG = "MainActivity";
    private static final int MSG_GET_NEWS = 1001;
    private ListView lv_news;
    private JsonRootBean jsonRootBean;
    private NewsAdapter newsAdapter;
    private Handler handler;
    private List<Result> resultList = new ArrayList<>();

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

        handler = new Handler(new Handler.Callback() {
     
            @Override
            public boolean handleMessage(@NonNull Message msg) {
     
                if (msg.what == MSG_GET_NEWS) {
     
                    newsAdapter.changeData(resultList);
                    return true;
                }
                return false;
            }
        });

        lv_news = findViewById(R.id.lv_duanzi);

        // 获取新闻列表
        getNewsData();

        newsAdapter = new NewsAdapter(MainActivity.this, resultList);

        lv_news.setAdapter(newsAdapter);

        // 单条新闻点击事件
        lv_news.setOnItemClickListener(new AdapterView.OnItemClickListener() {
     
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
     
                Result result = resultList.get(position);
                Intent intent = new Intent();
                // 第一种  每个属性一个put
                // intent.putExtra("TITLE", result.getTitle());
                //.....

                // 第二种
                // 使用Gson将对象转换成json字符串
                // 接收方再讲json字符串转回对象
                // 只需要putExtra一次
                Gson gson = new Gson();
                String jsonStr = gson.toJson(result);
                Log.e("MainActivity", "json = " + jsonStr);
                intent.putExtra("JSONSTR", jsonStr);
                intent.setClass(MainActivity.this, NewsDetailActivity.class);
                startActivity(intent);
            }
        });
    }

    /**
     * 获取新闻列表
     */
    private void getNewsData() {
     
        String url = "https://api.apiopen.top/getWangYiNews";
        OkHttpClient okHttpClient = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(url)
                .get()//默认就是GET请求,可以不写
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
     
            @Override
            public void onFailure(Call call, IOException e) {
     
                Log.e(TAG, "onFailure: ");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
     
//                Log.e(TAG, "onResponse: " + response.body().string());
                Gson gson = new Gson();
                jsonRootBean = gson.fromJson(response.body().string(), JsonRootBean.class);
                resultList = jsonRootBean.getResult();

                handler.sendEmptyMessage(MSG_GET_NEWS);
            }
        });

    }
}

MyUser的类定义文件

package com.example.demo;

import cn.bmob.v3.BmobUser;

public class MyUser extends BmobUser {
     
    String name;
    Number age;

    public String getName() {
     
        return name;
    }

    public void setName(String name) {
     
        this.name = name;
    }

    public Number getAge() {
     
        return age;
    }

    public void setAge(Number age) {
     
        this.age = age;
    }

    @Override
    public String toString() {
     
        return "MyUser{" +
                "usernmae = " + getUsername() +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Comment表的类定义文件

package com.example.demo;

import cn.bmob.v3.BmobObject;

public class Comment extends BmobObject {
     
    // 被评论的新闻标题
    String title;
    // 评论的用户
    MyUser myUser;
    // 评论的内容
    String content;

    public String getTitle() {
     
        return title;
    }

    public void setTitle(String title) {
     
        this.title = title;
    }

    public MyUser getMyUser() {
     
        return myUser;
    }

    public void setMyUser(MyUser myUser) {
     
        this.myUser = myUser;
    }

    public String getContent() {
     
        return content;
    }

    public void setContent(String content) {
     
        this.content = content;
    }

    @Override
    public String toString() {
     
        return "Comment{" +
                "title='" + title + '\'' +
                ", myUser=" + myUser +
                ", content='" + content + '\'' +
                '}';
    }
}

Favorite表的类定义文件

package com.example.demo;

import cn.bmob.v3.BmobObject;

/**
 * 收藏表
 */
public class Favorite extends BmobObject {
     
    private MyUser myUser;
    private Result result;
    private Boolean isFav;
    private String title;

    public String getTitle() {
     
        return title;
    }

    public void setTitle(String title) {
     
        this.title = title;
    }

    public MyUser getMyUser() {
     
        return myUser;
    }

    public void setMyUser(MyUser myUser) {
     
        this.myUser = myUser;
    }

    public Result getResult() {
     
        return result;
    }

    public void setResult(Result result) {
     
        this.result = result;
    }

    public Boolean getFav() {
     
        return isFav;
    }

    public void setFav(Boolean fav) {
     
        isFav = fav;
    }
}

查看新闻详情页面的布局文件


<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"
    tools:context=".NewsDetailActivity"
    android:orientation="vertical">

    <WebView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/wv_news"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <EditText
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:id="@+id/edt_comment"
            android:hint="请文明发言"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="评论"
            android:id="@+id/btn_comment"/>

        <ImageView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:padding="5dp"
            android:src="@drawable/fav_off"
            android:id="@+id/iv_fav"/>
    LinearLayout>

LinearLayout>

查看新闻详情的Java文件

package com.example.demo;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.gson.Gson;

import java.util.List;

import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.BmobUser;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.SaveListener;
import cn.bmob.v3.listener.UpdateListener;

public class NewsDetailActivity extends AppCompatActivity {
     
    private WebView wv_news;
    private EditText edt_comment;
    private Button btn_comment;
    private ImageView iv_fav;
    private boolean isFav = false;

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

        String jsonStr = getIntent().getStringExtra("JSONSTR");
        Gson gson = new Gson();
        Result result = gson.fromJson(jsonStr, Result.class);

        setTitle(result.getTitle());

        wv_news = findViewById(R.id.wv_news);
        wv_news.getSettings().setJavaScriptEnabled(true);
        wv_news.setWebViewClient(new WebViewClient() {
     
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
     
                view.loadUrl(url);
                return false;
            }
        });

        wv_news.loadUrl(result.getPath());

        edt_comment = findViewById(R.id.edt_comment);
        btn_comment = findViewById(R.id.btn_comment);

        btn_comment.setOnClickListener(new View.OnClickListener() {
     
            @Override
            public void onClick(View v) {
     
                // 当前用户是否已经登录
                MyUser myUser = BmobUser.getCurrentUser(MyUser.class);

                // 去登录或者注册
                if (myUser == null) {
     
                    Intent intent = new Intent();
                    intent.setClass(NewsDetailActivity.this, LoginActivity.class);
                    startActivity(intent);
                } else {
     
                    String content = edt_comment.getText().toString();
                    if (content.length() < 3) {
     
                        // 紫薯布丁
                        Toast.makeText(NewsDetailActivity.this, "字数不够",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }

                    Comment comment = new Comment();
                    comment.setTitle(result.getTitle());
                    comment.setMyUser(myUser);
                    comment.setContent(content);

                    comment.save(new SaveListener<String>() {
     
                        @Override
                        public void done(String s, BmobException e) {
     
                            if (e == null) {
     
                                Toast.makeText(NewsDetailActivity.this, "评论成功",
                                        Toast.LENGTH_SHORT).show();
                                edt_comment.setText("");

                                Intent intent = new Intent();
                                intent.setClass(NewsDetailActivity.this, CommentListActivity.class);
                                intent.putExtra("TITLE", result.getTitle());
                                startActivity(intent);
                            } else {
     
                                Toast.makeText(NewsDetailActivity.this, "评论失败 "
                                        + e.toString(), Toast.LENGTH_SHORT).show();
                            }
                        }
                    });

                }


            }
        });


        iv_fav = findViewById(R.id.iv_fav);
        iv_fav.setOnClickListener(new View.OnClickListener() {
     
            @Override
            public void onClick(View v) {
     
                // 判断当前用户是否已经登录
                // 当前用户是否已经登录
                MyUser myUser = BmobUser.getCurrentUser(MyUser.class);

                // 去登录或者注册
                if (myUser == null) {
     
                    Intent intent = new Intent();
                    intent.setClass(NewsDetailActivity.this, LoginActivity.class);
                    startActivity(intent);
                } else {
     
                    // 添加或者取消收藏
                    BmobQuery<Favorite> favoriteBmobQuery = new BmobQuery<>();
                    favoriteBmobQuery.addWhereEqualTo("title", result.getTitle());
                    favoriteBmobQuery.addWhereEqualTo("myUser",  myUser.getObjectId());
                    favoriteBmobQuery.findObjects(new FindListener<Favorite>() {
     
                        @Override
                        public void done(List<Favorite> list, BmobException e) {
     
                            if(e == null){
     
                                if(list.size() > 0){
     
                                    // 如果之前已有记录 直接更新这一条
                                    Favorite favorite = list.get(0);
                                    favorite.setFav(!isFav);
                                    favorite.update(new UpdateListener() {
     
                                        @Override
                                        public void done(BmobException e) {
     
                                            if (e == null) {
     
                                                if (isFav) {
     
                                                    Toast.makeText(NewsDetailActivity.this, "取消收藏成功",
                                                            Toast.LENGTH_SHORT).show();
                                                    isFav = false;
                                                    iv_fav.setImageResource(R.drawable.fav_off);
                                                    iv_fav.invalidate();
                                                } else {
     
                                                    Toast.makeText(NewsDetailActivity.this, "收藏成功",
                                                            Toast.LENGTH_SHORT).show();

                                                    isFav = true;
                                                    iv_fav.setImageResource(R.drawable.fav_on);
                                                    iv_fav.invalidate();
                                                }
                                            } else {
     
                                                Toast.makeText(NewsDetailActivity.this, "收藏失败 "
                                                        + e.toString(), Toast.LENGTH_SHORT).show();
                                            }
                                        }
                                    });
                                }else{
     
                                    // 之前并没有收藏记录
                                    Favorite favorite = new Favorite();
                                    favorite.setMyUser(myUser);
                                    favorite.setResult(result);
                                    favorite.setTitle(result.getTitle());
                                    // 当前状态是未收藏 点击就要收藏 反之亦然  所以对isFav取反
                                    favorite.setFav(!isFav);
                                    favorite.save(new SaveListener<String>() {
     
                                        @Override
                                        public void done(String s, BmobException e) {
     
                                            if (e == null) {
     
                                                if (isFav) {
     
                                                    Toast.makeText(NewsDetailActivity.this, "取消收藏成功",
                                                            Toast.LENGTH_SHORT).show();
                                                    isFav = false;
                                                    iv_fav.setImageResource(R.drawable.fav_off);
                                                    iv_fav.invalidate();
                                                } else {
     
                                                    Toast.makeText(NewsDetailActivity.this, "收藏成功",
                                                            Toast.LENGTH_SHORT).show();

                                                    isFav = true;
                                                    iv_fav.setImageResource(R.drawable.fav_on);
                                                    iv_fav.invalidate();
                                                }
                                            } else {
     
                                                Toast.makeText(NewsDetailActivity.this, "收藏失败 "
                                                        + e.toString(), Toast.LENGTH_SHORT).show();
                                            }
                                        }
                                    });
                                }
                            }else{
     
                                Log.e("queryFavStatus", "fail " + e.toString());
                            }
                        }
                    });

                }
            }
        });

        // 查询当前收藏的状态
        queryFavStatus(result);
    }

    // 拿到数据库保存的收藏状态
    private void queryFavStatus(Result result) {
     
        Log.e("queryFavStatus", "queryFavStatus " );
        MyUser myUser = BmobUser.getCurrentUser(MyUser.class);
        BmobQuery<Favorite> favoriteBmobQuery = new BmobQuery<>();
        favoriteBmobQuery.addWhereEqualTo("title", result.getTitle());
        favoriteBmobQuery.addWhereEqualTo("myUser", myUser.getObjectId());
        favoriteBmobQuery.findObjects(new FindListener<Favorite>() {
     
            @Override
            public void done(List<Favorite> list, BmobException e) {
     
                if(e == null){
     

                    Log.e("queryFavStatus", "success " + list.size());
                    if(list.size() > 0){
     
                        Favorite favorite = list.get(0);
                        isFav = favorite.getFav();
                        if(isFav){
     
                            iv_fav.setImageResource(R.drawable.fav_on);
                        }else{
     
                            iv_fav.setImageResource(R.drawable.fav_off);
                        }
                        iv_fav.invalidate();
                    }
                }else{
     
                    Log.e("queryFavStatus", "fail " + e.toString());
                }
            }
        });
    }
}

你可能感兴趣的:(网易新闻APP)