Android 模拟新闻APP显示界面滑动优化实例代码
程序员文章站
2023-11-26 09:52:52
内容:
1、滑动优化(滑动时不加载图片,停止才加载)
2、第一次进入时手动加载
代码如下:
1、界面布局
内容:
1、滑动优化(滑动时不加载图片,停止才加载)
2、第一次进入时手动加载
代码如下:
1、界面布局
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center"> <imageview android:id="@+id/image" android:src="@mipmap/ic_launcher" android:layout_width="60dp" android:layout_height="60dp" /> <linearlayout android:orientation="vertical" android:layout_marginleft="10dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <textview android:id="@+id/title_tv" android:text="title" android:textsize="15dp" android:maxlines="1" android:layout_width="match_parent" android:layout_height="wrap_content" /> <textview android:id="@+id/content_tv" android:text="content" android:textsize="10dp" android:maxlines="3" android:layout_width="match_parent" android:layout_height="wrap_content" /> </linearlayout> </linearlayout>
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" tools:context="com.example.leixiansheng.news.mainactivity"> <listview android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent"> </listview> </relativelayout>
2、开启异步解析数据
package com.example.leixiansheng.news; /** * created by leixiansheng on 2017/3/21. */ public class newsbean { public string viewurl; public string title; public string content; } package com.example.leixiansheng.news; import android.os.asynctask; import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.util.log; import android.widget.listview; import org.json.jsonarray; import org.json.jsonexception; import org.json.jsonobject; import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstream; import java.io.inputstreamreader; import java.io.unsupportedencodingexception; import java.net.url; import java.util.arraylist; import java.util.list; public class mainactivity extends appcompatactivity { private listview listview; private static string url = "http://www.imooc.com/api/teacher?type=4&num=30"; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); listview = (listview) findviewbyid(r.id.list_view); new newsasynctask().execute(url); } //*&*异步加载,处理耗时任务,ui更新 class newsasynctask extends asynctask<string, void, list<newsbean>> { @override protected list<newsbean> doinbackground(string... strings) { return getjsondata(strings[0]); } @override protected void onpostexecute(list<newsbean> newsbeen) { super.onpostexecute(newsbeen); newsadapter adapter = new newsadapter(mainactivity.this, newsbeen,listview); listview.setadapter(adapter); } } //*&*json解析网页获取数据 private list<newsbean> getjsondata(string url) { list<newsbean> newsbeanlist = new arraylist<>(); try { string jsonstring = readsteam(new url(url).openstream()); log.i("data", jsonstring); jsonobject jsonobject; newsbean newsbean; try { jsonobject = new jsonobject(jsonstring); jsonarray jsonarray = jsonobject.getjsonarray("data"); for (int i = 0; i < jsonarray.length(); i++) { jsonobject = jsonarray.getjsonobject(i); newsbean = new newsbean(); newsbean.content = jsonobject.getstring("description"); newsbean.title = jsonobject.getstring("name"); newsbean.viewurl = jsonobject.getstring("picsmall"); newsbeanlist.add(newsbean); } } catch (jsonexception e) { e.printstacktrace(); } } catch (ioexception e) { e.printstacktrace(); } return newsbeanlist; } //*&*读取数据流 private string readsteam(inputstream is) { inputstreamreader isr; string result = ""; try { string line = ""; isr = new inputstreamreader(is, "utf-8"); bufferedreader br = new bufferedreader(isr); try { while ((line = br.readline()) != null) { result += line; } } catch (ioexception e) { e.printstacktrace(); } } catch (unsupportedencodingexception e) { e.printstacktrace(); } return result; } }
3、自定义适配器(在此处设置滑动监听,以此来判断什么时候加载资源)
package com.example.leixiansheng.news; import android.content.context; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.abslistview; import android.widget.baseadapter; import android.widget.imageview; import android.widget.listview; import android.widget.textview; import java.util.list; /** * created by leixiansheng on 2017/3/21. */ public class newsadapter extends baseadapter implements abslistview.onscrolllistener{ private list<newsbean> newsbeanlist; private layoutinflater inflater; private imageloader imageloader; //图片加载 private int start; //第一个元素 private int end; //最后一个元素 private boolean isfirstin; //是否第一次进入 public static string[] urls; //所有资源 public newsadapter(context context, list<newsbean> newsbeanlist, listview listview) { this.newsbeanlist = newsbeanlist; inflater = layoutinflater.from(context); imageloader = new imageloader(listview); urls = new string[newsbeanlist.size()]; for (int i = 0; i < newsbeanlist.size(); i++) { urls[i] = newsbeanlist.get(i).viewurl; } isfirstin = true; listview.setonscrolllistener(this); } @override public int getcount() { return newsbeanlist.size(); } @override public object getitem(int i) { return newsbeanlist.get(i); } @override public long getitemid(int i) { return i; } @override public view getview(int i, view view, viewgroup viewgroup) { viewholder viewholder = null; if (view == null) { viewholder = new viewholder(); view = inflater.inflate(r.layout.item, null); viewholder.imageview = (imageview) view.findviewbyid(r.id.image); viewholder.title = (textview) view.findviewbyid(r.id.title_tv); viewholder.content = (textview) view.findviewbyid(r.id.content_tv); view.settag(viewholder); } else { viewholder = (viewholder) view.gettag(); } string url = newsbeanlist.get(i).viewurl; viewholder.imageview.setimageresource(r.mipmap.ic_launcher); //*&*设置标签,避免快速滑动listview出现位置误差 viewholder.imageview.settag(url); // new imageloader().showimagebythread(viewholder.imageview, url); imageloader.showimageviewbyasynctask(viewholder.imageview,url); viewholder.title.settext(newsbeanlist.get(i).title); viewholder.content.settext(newsbeanlist.get(i).content); return view; } //*&*优化 class viewholder { public textview title; public textview content; private imageview imageview; } //滑动监听 @override public void onscrollstatechanged(abslistview abslistview, int i) { if (i == scroll_state_idle) { //停止状态:加载图片 imageloader.loadimages(start, end); } else { //滑动状态:停止加载 imageloader.cancelalltasks(); } } /** * * @param abslistview * @param i 第一个元素 * @param i1 元素数量 * @param i2 */ @override public void onscroll(abslistview abslistview, int i, int i1, int i2) { start = i; end = i + i1; //第一次进入需要手动加载 if (isfirstin && i1 > 0) { imageloader.loadimages(start, end); isfirstin = false; } } }
package com.example.leixiansheng.news; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.os.asynctask; import android.os.handler; import android.os.message; import android.util.lrucache; import android.widget.imageview; import android.widget.listview; import java.io.bufferedinputstream; import java.io.ioexception; import java.io.inputstream; import java.net.httpurlconnection; import java.net.malformedurlexception; import java.net.url; import java.util.hashset; import java.util.set; /** * created by leixiansheng on 2017/3/21. */ public class imageloader { private imageview mimageview; private string murl; //*&*创建缓存 private lrucache<string, bitmap> lrucache; private listview listview; private set<newsasynctask> mtask; public imageloader(listview listview) { this.listview = listview; mtask = new hashset<>(); //*&*获取最大内存 int maxmemory = (int) runtime.getruntime().maxmemory(); //设置缓存大小 int lrucachesize = maxmemory / 4; lrucache = new lrucache<string, bitmap>(lrucachesize) { @override protected int sizeof(string key, bitmap value) { //获取每个数据大小 return value.getbytecount(); } }; } //添加数据到缓存 public void addbitmaptolrucache(string url, bitmap bitmap) { if (getbitmapfromlrucache(url) == null) { lrucache.put(url, bitmap); } } //从缓存中获取数据 public bitmap getbitmapfromlrucache(string url) { return lrucache.get(url); } private handler handler = new handler() { @override public void handlemessage(message msg) { super.handlemessage(msg); if (mimageview.gettag().equals(murl)) { mimageview.setimagebitmap((bitmap) msg.obj); } } }; public void showimagebythread(imageview imageview, final string url) { mimageview = imageview; murl = url; new thread() { @override public void run() { super.run(); bitmap bitmap = getbitmapfromurl(url); message message = message.obtain(); message.obj = bitmap; handler.sendmessage(message); } }.start(); } public bitmap getbitmapfromurl(string urlstring) { bitmap bitmap; inputstream is = null; try { url url = new url(urlstring); httpurlconnection connection = (httpurlconnection) url.openconnection(); is = new bufferedinputstream(connection.getinputstream()); bitmap = bitmapfactory.decodestream(is); connection.disconnect(); //模拟网速卡顿时 // try { // thread.sleep(1000); // } catch (interruptedexception e) { // e.printstacktrace(); // } return bitmap; } catch (malformedurlexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } finally { try { is.close(); } catch (ioexception e) { e.printstacktrace(); } } return null; } public void showimageviewbyasynctask(imageview imageview, string url) { //判断是否已经缓存 bitmap bitmap = getbitmapfromlrucache(url); //没有缓存则从新下载 if (bitmap == null) { imageview.setimageresource(r.mipmap.ic_launcher); } else { imageview.setimagebitmap(bitmap); } } //加载从start到end的所有图片 public void loadimages(int start, int end) { for (int i = start; i < end; i++) { string url = newsadapter.urls[i]; //判断是否已经缓存 bitmap bitmap = getbitmapfromlrucache(url); //没有缓存则从新下载 if (bitmap == null) { newsasynctask task = new newsasynctask(url); task.execute(url); mtask.add(task); } else { imageview imageview = (imageview) listview.findviewwithtag(url); imageview.setimagebitmap(bitmap); } } } public void cancelalltasks() { if (mtask != null) { for (newsasynctask task : mtask) { task.cancel(false); } } } private class newsasynctask extends asynctask<string, void, bitmap> { // private imageview imageview; private string url; public newsasynctask(string url) { // this.imageview = imageview; this.url = url; } @override protected bitmap doinbackground(string... strings) { string url = strings[0]; //从网络获取图片 bitmap bitmap = getbitmapfromurl(url); if (bitmap != null) { //将不在缓存中的图片加入到缓存 addbitmaptolrucache(url, bitmap); } return bitmap; } @override protected void onpostexecute(bitmap bitmap) { super.onpostexecute(bitmap); imageview imageview = (imageview) listview.findviewwithtag(url); if (imageview != null && bitmap != null) { imageview.setimagebitmap(bitmap); } mtask.remove(this); } } }
4、注册声明权限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.leixiansheng.news"> <uses-permission android:name="android.permission.internet"/> <application android:allowbackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsrtl="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> </application> </manifest>
以上所述是小编给大家介绍的android 模拟新闻app显示界面滑动优化实例代码,希望对大家有所帮助