Android 模拟新闻APP显示界面滑动优化实例代码

内容:

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显示界面滑动优化实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Android滑动优化高仿QQ6.0侧滑菜单(滑动优化)

     推荐阅读:Android使用ViewDragHelper实现仿QQ6.0侧滑界面(一) 但是之前的实现,只是简单的可以显示和隐藏左侧的菜单,但是特别生硬,而且没有任何平滑的趋势,那么今天就来优化一下吧,加上平滑效果,而且可以根据手势滑动的方向来判断是否是显示和隐藏. 首先先来实现手势判断是否隐藏和显示 这里就要用到了一个方法了,如下: 这个是ViewDradHelper里面的方法: /** * 当view被释放的时候处理的事情(松手) * * @param releasedChild 被释放的

  • Android 模拟新闻APP显示界面滑动优化实例代码

    内容: 1.滑动优化(滑动时不加载图片,停止才加载) 2.第一次进入时手动加载 代码如下: 1.界面布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:

  • Android studio实现app登录界面

    Android studio设计app登录界面UI界面设计在设计登录界面时,可以使用不同布局方式来实现该功能,通常情况下使用的是LinearLayout(线性布局)和TableLayout(表格布局),在本文中使用线性布局.登陆界面需要几项必不可少的控件,如下所示: TextView:用于显示标题和“用户名"和"密码"的提示;标题设置 <TextView        android:layout_width="wrap_content"     

  • Android 自定义 HorizontalScrollView 打造多图片OOM 的横向滑动效果(实例代码)

    自从Gallery被谷歌废弃以后,Google推荐使用ViewPager和HorizontalScrollView来实现Gallery的效果.的确HorizontalScrollView可以实现Gallery的效果,但是HorizontalScrollView存在一个很大的问题,如果你仅是用来展示少量的图片,应该是没问题的,但是如果我希望HorizontalScrollView可以想ViewPager一样,既可以绑定数据集(动态改变图片),还能做到,不管多少图片都不会OOM(ViewPager内

  • Android 滑动拦截实例代码解析

    废话不多说了,直接给大家贴代码了,具体代码如下所示: package demo.hq.com.fby; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.LinearLayout; /** * Created by huqing on 2016/12/7.

  • Android 仿今日头条简单的刷新效果实例代码

    点击按钮,先自动进行下拉刷新,也可以手动刷新,刷新完后,最后就多一行数据.有四个选项卡. 前两天导师要求做一个给本科学生预定机房座位的app,出发点来自这里.做着做着遇到很多问题,都解决了.这个效果感觉还不错,整理一下. MainActivity package com.example.fragmentmytest; import android.content.DialogInterface; import android.graphics.Color; import android.os.B

  • Android利用ZXing扫描二维码的实例代码解析

    相关阅读: Android开发框架之自定义ZXing二维码扫描界面并解决取景框拉伸问题 此项目源码地址:请点击这里 看一下zxing的项目结构,我这里直接拿过来用的 看一下扫码的activity: package com.fanyafeng.barcode.activity; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle

  • Android 中TabLayout自定义选择背景滑块的实例代码

    TabLayout是Android 的Material Design包中的一个控件,可以和V4包中的ViewPager搭配产生一个联动的效果.这里我自定义了一个滑块能够跟随TabLayout进行滑动选择的SliderLayout.效果见下图(白色方框): 下面是SliderLayout的源码: import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawabl

  • Android获取应用程序大小和缓存的实例代码

    info package com.qin.appsize; import android.content.Intent; import android.graphics.drawable.Drawable; //Model类 ,用来存储应用程序信息 public class AppInfo { private String appLabel; //应用程序标签 private Drawable appIcon ; //应用程序图像 private Intent intent ; //启动应用程序

  • android中图片加载到内存的实例代码

    本文演示android中图片加载到内存 首先设计界面: 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="matc

  • Android 自定义弹出菜单和对话框功能实例代码

    Android 开发当中,可能会存在许多自定义布局的需求,比如自定义弹出菜单(popupWindow),以及自定义对话框(Dialog). 话不多说,直接上图片. 先讲第一种,自定义PopUpWindow 1.popupWindow protected void showPopWindow(View view, final int pos){ WindowManager wm= (WindowManager) myContext.getSystemService(Context.WINDOW_S

随机推荐