新闻界面
通过ListView实现新闻的界面,android发送请求给服务器,服务器返回需要展示的json数据。android解析新闻数据通过ListView实现图文混排。
为什么使用异步加载:
Android单线程模型。
耗时操作阻塞UI进程。
异步加载最常用的两种方式:
1.多线程/线程池
2.AsyncTask
如图所示:
1. 创建项目MyApplication。
2. 创建布局
2.1 主页面
主页面添加ListView组件。
MyApplication/app/src/main/res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="MainActivity">
<ListView
android:id="@+id/new_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
2.2 创建一个Item
就是每一个新闻栏的设计。
MyApplication/app/src/main/res/layout/item_layout.xml
<?xml version=";1.0"; encoding=";utf-8";?>
<LinearLayout xmlns:android=";http://schemas.android.com/apk/res/android";
xmlns:tools=";http://schemas.android.com/tools";
android:orientation=";horizontal";
android:layout_width=";match_parent";
android:layout_height=";wrap_content";
android:padding=";4dp";>
<ImageView
android:id=";@+id/new_pic";
android:layout_width=";64dp";
android:layout_height=";64dp";
android:src=";@mipmap/ic_launcher";/>
<LinearLayout
android:layout_width=";match_parent";
android:layout_height=";match_parent";
android:orientation=";vertical";>
<LinearLayout
android:layout_width=";match_parent";
android:layout_height=";wrap_content";
android:layout_weight=";1.5";
android:orientation=";horizontal";>
<TextView
android:id=";@+id/new_title";
android:layout_width=";wrap_content";
android:layout_height=";wrap_content";
android:text=";Title";
android:layout_weight=";1";
android:layout_gravity=";center";
android:textSize=";20sp";/>
<TextView
android:id=";@+id/new_time";
android:layout_width=";wrap_content";
android:layout_height=";wrap_content";
android:text=";2019-12-28 12:46:00";
android:layout_gravity=";center";
android:textSize=";13sp";/>
</LinearLayout>
<TextView
android:id=";@+id/new_desc";
android:layout_width=";wrap_content";
android:layout_height=";wrap_content";
android:text=";desc";
android:layout_weight=";1";
android:textSize=";15sp";/>
<TextView
android:id=";@+id/new_content";
android:layout_width=";wrap_content";
android:layout_height=";wrap_content";
android:text=";content";
android:visibility=";gone";/>
</LinearLayout>
</LinearLayout>
2.3. 创建Bean。
MyApplication/app/src/main/java/com/example/myapplication/NewBean.java
package com.example.myapplication;
public class NewBean {
private String id;
private String title;
private String desc;
private String time;
private String contentUrl;
private String picUrl;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getContentUrl() {
return contentUrl;
}
public void setContentUrl(String contentUrl) {
this.contentUrl = contentUrl;
}
public String getPicUrl() {
return picUrl;
}
public void setPicUrl(String picUrl) {
this.picUrl = picUrl;
}
}
2.4. AsyncTask分析
异步请求json数据解析。
MyApplication/app/src/main/java/com/example/myapplication/MainActivity.java
package com.example.myapplication;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private static String URL = "http://news.6liu.top/news";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//默认加载的页面
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.new_main);
//发起URL请求
new NewsAsyncTask().execute(URL);
}
/**
* 实现网络的异步访问
*/
class NewsAsyncTask extends AsyncTask<String, Void, List<NewBean>>{
@Override
protected List<NewBean> doInBackground(String... strings) {
return getJsonData(strings[0]);
}
@Override
protected void onPostExecute(List<NewBean> newBeans) {
super.onPostExecute(newBeans);
NewsAdapter adapter = new NewsAdapter(MainActivity.this, newBeans);
mListView.setAdapter(adapter);
}
}
/**
* 将获取到的json数据转化为NewBean对象
* @param url
* @return
*/
private List<NewBean> getJsonData(String url) {
List<NewBean> newsBeanList = new ArrayList<>();
try {
String jsonString = readStream(new URL(url).openStream());
NewBean newBean;
//解析Json数据
JSONObject jsonObject;
try{
jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray("data");
for (int i=0; i<jsonArray.length(); i++){
jsonObject = jsonArray.getJSONObject(i);
newBean = new NewBean();
newBean.setId(jsonObject.getString("id"));
newBean.setTitle(jsonObject.getString("title"));
newBean.setDesc(jsonObject.getString("desc"));
newBean.setTime(jsonObject.getString("time"));
newBean.setContentUrl(jsonObject.getString("content_url"));
newBean.setPicUrl(jsonObject.getString("pic_url"));
newsBeanList.add(newBean);
}
}catch (JSONException e){
e.printStackTrace();
}
} catch (IOException e){
e.printStackTrace();
}
return newsBeanList;
}
/**
* 用is解析网页返回的数据
* @param is
* @return
*/
private String readStream(InputStream is){
InputStreamReader isr;
String result = "";
try {
String line = "";
isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null){
result += line;
}
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
return result;
}
}
2.5. 文艺复现BaseAdapter
创建NewsAdapter实现BaseAdapter抽象类放入ListView对象。 MyApplication/app/src/main/java/com/example/myapplication/NewsAdapter.java
package com.example.myapplication;
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 java.util.List;
public class NewsAdapter extends BaseAdapter {
private List<NewBean> mList;
private LayoutInflater mInflater;
public NewsAdapter(Context context, List<NewBean> data){
mList = data;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if(convertView == null){
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item_layout, null);
viewHolder.newPic = convertView.findViewById(R.id.new_pic);
viewHolder.newTitle = convertView.findViewById(R.id.new_title);
viewHolder.newTime = convertView.findViewById(R.id.new_time);
viewHolder.newDesc = convertView.findViewById(R.id.new_desc);
viewHolder.newContent = convertView.findViewById(R.id.new_content);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
#这里图片写死了
viewHolder.newPic.setImageResource(R.mipmap.ic_launcher);
viewHolder.newTitle.setText(mList.get(position).getTitle());
viewHolder.newTime.setText(mList.get(position).getTime());
viewHolder.newDesc.setText(mList.get(position).getDesc());
viewHolder.newContent.setText(mList.get(position).getContentUrl());
return convertView;
}
class ViewHolder{
public TextView newTitle, newTime, newDesc, newContent;
public ImageView newPic;
}
}
2.6. 注意
增加网络访问:
<uses-permission android:name="android.permission.INTERNET" />
高版本的api不支持明文访问,就是不支持Http访问,加入一下语句:
android:usesCleartextTraffic="true"
MyApplication/app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="NewsActivity"></activity>
</application>
</manifest>
评论