移动设备交互应用 实验二 我的头条
Posted 上山打老虎D
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了移动设备交互应用 实验二 我的头条相关的知识,希望对你有一定的参考价值。
一、实验目的与内容:
目的:
掌握安卓中活动的编写、自定义用户界面的开发、能使用HTTP协议访问网络;并能通过自学能适当完善该APP界面,并使界面尽量美观。
内容要求:
-
请尽量模拟如下APP界面的功能,参考:
https://play.google.com/store/apps/details?id=mark.h.my_news_app&hl=en_US
-
该实现的界面应至少包含3个菜单,分别展示个人3个方面的信息,菜单之间要表现出一定的差异性;每个菜单可以包含2-5个条目,每个条目能响应个人某方面的偏好信息;此外,如果是响应网页,需同时体现出a) 采用浏览器浏览 与 b) 下载到本地 两种技术方案。
-
尽量多的应用参考书《第一行代码 android》第二版第2章(活动)、第3章(UI开发)与第9章(网络技术)的各个知识点。
注意:
- 实验报告中需要有功能的描述、实验结果的截屏图像及详细说明;
- 该实验报告的所需的部分内容需要自学(如第9章);
- 也欢迎采用其它章节的知识点完成本次实验报告,如果实现的功能言之合理,会考虑酌情加分。
二、实验过程和代码与结果
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~34行完成了包名以及对应类的引用,此处不做详细解释。
- 第35行到38行定义对应的参数,此处使用了两个List容器,用来存储对应的fragment内容和网页上的每条新闻内容。
- 第41行到64行重写onCreate函数,定义左侧的actionBar滑出菜单。添加监听事件,当检测到鼠标点击时展示actionBar,在actionBar开启状态下点击其他位置则关闭actionBar。
- 第66到104行利用线程去从Json里获取数据进行新闻的展示。首先,通过json获取对应API的数据。解析返回数据结构后,建立对应JSONObject,再通过JSONArray提取对应返回的“data”数据并将每一条新闻分开。通过利用for循环遍历jsonArray分离每一条新闻。对于每一条新闻,通过jsonObject的getString方法,获取对应的标题以及跳转链接。为了防止相应时间过长而造成个别新闻相应时间过长而死循环,此处也设置了相应的Timeout判断时间,即超过这个时间便认定为超时,进入下一个新闻的读取。在完成每个新闻的读取后,创建对应的新闻类后,将对应新闻放入webNameList容器中。此时,一条新闻的读取已经完成,通过循环遍历jsonArray完成对所有新闻的读取。
- 第106到109行通过onCreateOptionsMenu来创建菜单,创建左侧滑出的菜单。
- 第112行到162行定义了刷新功能,如果检测到点击了刷新按钮,则弹出“You clicked refresh”的提示并重新获取新闻,获取新闻的方式与前面的方式一样,此处不重复介绍。
- 第164行到174行定义初始化页面的方法,并增加对应的fragment以完成tab的切换。
- 第176到第188行实现对应的fragment适配器以刷新页面数据,此处重写了createFragment与getItemCount两个方法
- 第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() {
以上是关于移动设备交互应用 实验二 我的头条的主要内容,如果未能解决你的问题,请参考以下文章