移动设备交互应用 实验二 我的头条

Posted 上山打老虎D

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了移动设备交互应用 实验二 我的头条相关的知识,希望对你有一定的参考价值。

一、实验目的与内容:

目的:
掌握安卓中活动的编写、自定义用户界面的开发、能使用HTTP协议访问网络;并能通过自学能适当完善该APP界面,并使界面尽量美观。
内容要求:

  1. 请尽量模拟如下APP界面的功能,参考:
    https://play.google.com/store/apps/details?id=mark.h.my_news_app&hl=en_US
    在这里插入图片描述

  2. 该实现的界面应至少包含3个菜单,分别展示个人3个方面的信息,菜单之间要表现出一定的差异性;每个菜单可以包含2-5个条目,每个条目能响应个人某方面的偏好信息;此外,如果是响应网页,需同时体现出a) 采用浏览器浏览 与 b) 下载到本地 两种技术方案。

  3. 尽量多的应用参考书《第一行代码 android》第二版第2章(活动)、第3章(UI开发)与第9章(网络技术)的各个知识点。

注意:

  1. 实验报告中需要有功能的描述、实验结果的截屏图像及详细说明;
  2. 该实验报告的所需的部分内容需要自学(如第9章);
  3. 也欢迎采用其它章节的知识点完成本次实验报告,如果实现的功能言之合理,会考虑酌情加分。

二、实验过程和代码与结果

1.“我的头条”APP的构建过程及结果

本实验共包含四个java文件接下来按照顺序进行介绍:
①MainActivity.java

package com.example.todaytest;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;

import com.google.android.material.navigation.NavigationView;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;

import org.json.JSONArray;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private final List<Fragment> fragmentList = new ArrayList<>();
    private final String[] titles = {"Recommend", "Science", "Sport", "Entertainment", "Fashion"};
    public volatile List<WebList> webNameList = new ArrayList<>();
    private DrawerLayout mDrawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle("");
        setSupportActionBar(toolbar);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        NavigationView navView = (NavigationView) findViewById(R.id.nav_view);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
        }
        navView.setCheckedItem(R.id.nav_call);
        navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem item) {
                mDrawerLayout.closeDrawers();
                return true;
            }
        });


        new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    Document doc = Jsoup.connect("http://v.juhe.cn/toutiao/index?type=&key=f771f2aa48bd48c7de10e40ab22d9228").userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/86.0.4240.111 Safari/537.36").ignoreContentType(true).get();
                    String data_js = doc.text();

                    JSONObject jobj = new JSONObject(data_js).getJSONObject("result");
                    JSONArray jsonArray = jobj.getJSONArray("data");
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        String title = jsonObject.getString("title");
                        String url = jsonObject.getString("url");
                        byte[] bytes;
                        String img_url = jsonObject.getString("thumbnail_pic_s");
                        URL url1 = new URL(img_url);
                        HttpURLConnection connection = (HttpURLConnection) url1.openConnection();


                        connection.setConnectTimeout(5000);
                        connection.setRequestMethod("GET");
                        int code = connection.getResponseCode();
                        if (code == 200) {
                            InputStream is = connection.getInputStream();
                            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                            byte[] buffer = new byte[1024];
                            int len;
                            while ((len = is.read(buffer)) != -1) {
                                byteArrayOutputStream.write(buffer, 0, len);
                            }
                            bytes = byteArrayOutputStream.toByteArray();
                            WebList webList = new WebList(title, url, bytes);
                            webNameList.add(webList);
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
//                    System.out.println("error occurred!");
                }
            }
        }).start();
        initView();
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                mDrawerLayout.openDrawer(GravityCompat.START);
                break;

            case R.id.settings:
                Toast.makeText(this, "You clicked refresh", Toast.LENGTH_SHORT).show();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Document doc = Jsoup.connect("http://v.juhe.cn/toutiao/index?type=&key=f771f2aa48bd48c7de10e40ab22d9228").userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36").ignoreContentType(true).get();
                            String data_js = doc.text();
                            JSONObject jobj = new JSONObject(data_js).getJSONObject("result");
                            JSONArray jsonArray = jobj.getJSONArray("data");
                            for (int i = 0; i < jsonArray.length(); i++) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                String title = jsonObject.getString("title");
                                String url = jsonObject.getString("url");

                                byte[] bytes;
                                String img_url = jsonObject.getString("thumbnail_pic_s");
                                URL url1 = new URL(img_url);
                                HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
                                connection.setConnectTimeout(5000);
                                connection.setRequestMethod("GET");
                                int code = connection.getResponseCode();
                                if (code == 200) {
                                    InputStream is = connection.getInputStream();
                                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                                    byte[] buffer = new byte[1024];
                                    int len;
                                    while ((len = is.read(buffer)) != -1) {
                                        byteArrayOutputStream.write(buffer, 0, len);
                                    }
                                    bytes = byteArrayOutputStream.toByteArray();
                                    WebList webList = new WebList(title, url, bytes);
                                    webNameList.add(webList);
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
                break;
            default:
        }
        return true;
    }

    private void initView() {
        ViewPager2 viewPager2 = findViewById(R.id.view_pager2);
        TabLayout tabLayout = findViewById(R.id.tab_layout);

        fragmentList.add(WebListFragment.newInstance("Recommend"));
        fragmentList.add(WebListFragment.newInstance("Science"));
        fragmentList.add(WebListFragment.newInstance("Sport"));
        fragmentList.add(WebListFragment.newInstance("Entertainment"));
        fragmentList.add(WebListFragment.newInstance("Fashion"));

        viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);

        viewPager2.setAdapter(new FragmentStateAdapter(this) {

            @NonNull
            @Override
            public Fragment createFragment(int position) {

                return fragmentList.get(position);
            }

            @Override
            public int getItemCount() {
                return fragmentList.size();
            }
        });
        TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager2, false, new TabLayoutMediator.TabConfigurationStrategy() { // 设置tablayout和viewpager2联动
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
                tab.setText(titles[position]);
            }
        });
        tabLayoutMediator.attach();
    }

}
  1. 1~34行完成了包名以及对应类的引用,此处不做详细解释。
  2. 第35行到38行定义对应的参数,此处使用了两个List容器,用来存储对应的fragment内容和网页上的每条新闻内容。
  3. 第41行到64行重写onCreate函数,定义左侧的actionBar滑出菜单。添加监听事件,当检测到鼠标点击时展示actionBar,在actionBar开启状态下点击其他位置则关闭actionBar。
  4. 第66到104行利用线程去从Json里获取数据进行新闻的展示。首先,通过json获取对应API的数据。解析返回数据结构后,建立对应JSONObject,再通过JSONArray提取对应返回的“data”数据并将每一条新闻分开。通过利用for循环遍历jsonArray分离每一条新闻。对于每一条新闻,通过jsonObject的getString方法,获取对应的标题以及跳转链接。为了防止相应时间过长而造成个别新闻相应时间过长而死循环,此处也设置了相应的Timeout判断时间,即超过这个时间便认定为超时,进入下一个新闻的读取。在完成每个新闻的读取后,创建对应的新闻类后,将对应新闻放入webNameList容器中。此时,一条新闻的读取已经完成,通过循环遍历jsonArray完成对所有新闻的读取。
  5. 第106到109行通过onCreateOptionsMenu来创建菜单,创建左侧滑出的菜单。
  6. 第112行到162行定义了刷新功能,如果检测到点击了刷新按钮,则弹出“You clicked refresh”的提示并重新获取新闻,获取新闻的方式与前面的方式一样,此处不重复介绍。
  7. 第164行到174行定义初始化页面的方法,并增加对应的fragment以完成tab的切换。
  8. 第176到第188行实现对应的fragment适配器以刷新页面数据,此处重写了createFragment与getItemCount两个方法
  9. 第189到196行完成设置tablayout和viewpager2联动

②WebListFragment.java

package com.example.todaytest;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

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

import org.json.JSONArray;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class WebListFragment extends Fragment {
    private static final String KEY = "key";
    private static String val;
    private final Object lock = new Object();
    public volatile List<WebList> webNameList = new ArrayList<>();

    public WebListFragment() {
    }

    public static WebListFragment newInstance(String ty) {
        val = ty;
        WebListFragment fragment = new WebListFragment();
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public synchronized View onCreateView(LayoutInflater inflater, ViewGroup container,
                                          Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fg_weblist, container, false);
        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        MainActivity activity = (MainActivity) getActivity();
        assert activity != null;
        webNameList = activity.webNameList;
        LinearLayoutManager layoutManager = new LinearLayoutManager(view.getContext());
        recyclerView.setLayoutManager(layoutManager);
        WebAdapter adapter = new WebAdapter(webNameList, view.getContext());
        recyclerView.setAdapter(adapter);
        return view;
    }

    private void init_view_data() {
        以上是关于移动设备交互应用 实验二 我的头条的主要内容,如果未能解决你的问题,请参考以下文章

移动设备交互应用 大作业

移动设备交互应用 实验一 熟悉Android编程开发环境

添加两个窗格的平板电脑布局会导致在移动设备中找不到视图(小于w600dp)

无法移动到嵌套子导航组件中的父片段?

Vue黑马头条移动端项目day01

第四章 Windows的图形设备接口及Windows绘图 P83 4-6