实现如图效果(“下拉刷新”,“加载更多”用第三方组件自带的效果即可),其中图片使用Universal-Image-Loader设置内存缓存的最大值为20M,导入PullToRefresh库,并使用PullToRefreshScrollView组件实现下拉刷新、上拉加载更多。
1.封装网络请求工具类和网络状态判断工具类,应用打开时,判断网络是否可用,不可用时弹出对话框提示用户进入设置页面,网络正常时弹出吐司,提示网络正常。
2.使用ViewPage+Handler完成无限轮播效果,轮播图使用Universal-Image-Loader加载网上图片资源(图片链接自己准备),给轮播图里的图片设置点击事件,点击后打开“https://www.baidu.com”(轮播图使用第三方0分)
3.http://120.27.23.105/product/searchProducts?keywords=%E7%AC%94%E8%AE%B0%E6%9C%AC&source=android&page=1(接口)
1.MainActivity
package com.example.zuoye0111; import android.annotation.SuppressLint; import android.os.Handler; import android.os.Message; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.ListView; import android.widget.ScrollView; import com.google.gson.Gson; import com.handmark.pulltorefresh.library.PullToRefreshBase; import com.handmark.pulltorefresh.library.PullToRefreshScrollView; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private PullToRefreshScrollView scrollView; private TabLayout tabLayout; private ViewPager viewPager; private ListView listView; private List<String> list; private int index=1; private String url = "http://120.27.23.105/product/searchProducts?keywords=%E7%AC%94%E8%AE%B0%E6%9C%AC&source=android&page="+index; private RequestData requestData; private MyAdapter2 myAdapter2; private int type=1;//1.刷新。2.加载 private List<RequestData.DataBean> lists=new ArrayList<>(); @SuppressLint("HandlerLeak") private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { //获取当前页面的值 int item = viewPager.getCurrentItem(); item++; viewPager.setCurrentItem(item); handler.sendEmptyMessageDelayed(0,1000); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //找到资源控件的ID scrollView = findViewById(R.id.p_sv); tabLayout=findViewById(R.id.my_tab); viewPager = findViewById(R.id.view_pager); listView = findViewById(R.id.my_lv); //实现菜单布局 tabLayout.addTab(tabLayout.newTab().setText("考试0")); tabLayout.addTab(tabLayout.newTab().setText("考试1")); tabLayout.addTab(tabLayout.newTab().setText("考试2")); tabLayout.addTab(tabLayout.newTab().setText("考试3")); tabLayout.addTab(tabLayout.newTab().setText("考试4")); tabLayout.addTab(tabLayout.newTab().setText("考试5")); //实现自动轮播 list = new ArrayList<>(); list.add("http://img01.sogoucdn.com/app/a/100520093/ac75323d6b6de243-cbe931c159ab22f1-599d36035b706cc2f262645280283fba.jpg"); list.add("http://img01.sogoucdn.com/app/a/100520093/ac75323d6b6de243-6f95e32275e1e6d6-e0102d9daf85121e712e3bf385e73fe2.jpg"); list.add("http://img03.sogoucdn.com/app/a/100520093/e44591f3bb81ec2f-f6104c63e22b94db-b0a249395f2349f87cf67a5b1a21a514.jpg"); list.add("http://img02.sogoucdn.com/app/a/100520093/30c40e020f63f81f-85679ec6a342f6f1-852857942ff2617a603a1dfe05738c96.jpg"); //创建适配器 MyAdapter myAdapter = new MyAdapter(MainActivity.this, list); viewPager.setAdapter(myAdapter); //设置图片默认显示在中间 viewPager.setCurrentItem(list.size()*10000); //实现自动轮播 handler.sendEmptyMessageDelayed(0,1000); initpsc(); //设置请求网络 requestNetData(); } private void requestNetData() { if(NetStateUtil.isConn(this)) { MyTask myTask = new MyTask(new MyTask.Icallbacks() { @Override public void updateUiByjson(String jsonstr) { //进行解析 Gson gson = new Gson(); requestData = gson.fromJson(jsonstr, RequestData.class); if(type==1){ lists.clear(); } lists.addAll(requestData.getData()); //设置适配器 setAdapter(); //关闭头尾布局 scrollView.onRefreshComplete(); } }); myTask.execute(url); } } private void setAdapter() { if(myAdapter2==null) { myAdapter2 = new MyAdapter2(MainActivity.this, lists); listView.setAdapter(myAdapter2); }else{ myAdapter2.notifyDataSetChanged(); } } private void initpsc() { //设置模式 scrollView.setMode(PullToRefreshBase.Mode.BOTH); //设置监听 scrollView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ScrollView>() { @Override//下拉刷新 public void onPullDownToRefresh(PullToRefreshBase<ScrollView> refreshView) { type=1; index=1; url="http://120.27.23.105/product/searchProducts?keywords=%E7%AC%94%E8%AE%B0%E6%9C%AC&source=android&page="+index; //设置请求网络 requestNetData(); } @Override//上拉加载 public void onPullUpToRefresh(PullToRefreshBase<ScrollView> refreshView) { type=2; index++; url="http://120.27.23.105/product/searchProducts?keywords=%E7%AC%94%E8%AE%B0%E6%9C%AC&source=android&page="+index; //设置请求网络 requestNetData(); } }); } }
2.自动轮播图的适配器
package com.example.zuoye0111; import android.content.Context; import android.graphics.Bitmap; import android.support.annotation.NonNull; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer; import java.util.List; /** * Created by dell on 2018/1/11. */ class MyAdapter extends PagerAdapter{ private Context context; private List<String> list; private DisplayImageOptions options; public MyAdapter(Context context, List<String> list) { this.context=context; this.list=list; options = new DisplayImageOptions.Builder() .cacheInMemory(true)//使用内存缓存 .cacheOnDisk(true)//使用磁盘缓存 .showImageOnLoading(R.mipmap.ic_launcher)//设置正在下载的图片 .showImageForEmptyUri(R.mipmap.ic_launcher)//url为空或请求的资源不存在时 .showImageOnFail(R.mipmap.ic_launcher)//下载失败时显示的图片 .bitmapConfig(Bitmap.Config.RGB_565)//设置图片色彩模式 1px=2字节 .imageScaleType(ImageScaleType.EXACTLY)//设置图片的缩放模式 .displayer(new RoundedBitmapDisplayer(100))//设置圆角 30代表半径 自定义 .build(); } @Override public int getCount() { return Integer.MAX_VALUE;//将图片设置为最大 } @Override public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { return view==object; } @NonNull @Override public Object instantiateItem(@NonNull ViewGroup container, int position) { //创建实现图片的控件 ImageView imageView = new ImageView(context); //连接网络获取并添加图片 ImageLoader.getInstance().displayImage(list.get(position%list.size()),imageView,options); //将控件设置给容器 container.addView(imageView); //返回控件 return imageView; } @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { container.removeView((View) object); } }3.条目显示的适配器
package com.example.zuoye0111; import android.content.Context; import android.graphics.Bitmap; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer; import java.util.List; /** * Created by dell on 2018/1/11. */ class MyAdapter2 extends BaseAdapter{ private Context context; private List<RequestData.DataBean> data; private DisplayImageOptions options; public MyAdapter2(Context context, List<RequestData.DataBean> data) { this.context=context; this.data=data; options = new DisplayImageOptions.Builder() .cacheInMemory(true)//使用内存缓存 .cacheOnDisk(true)//使用磁盘缓存 .showImageOnLoading(R.mipmap.ic_launcher)//设置正在下载的图片 .showImageForEmptyUri(R.mipmap.ic_launcher)//url为空或请求的资源不存在时 .showImageOnFail(R.mipmap.ic_launcher)//下载失败时显示的图片 .bitmapConfig(Bitmap.Config.RGB_565)//设置图片色彩模式 1px=2字节 .imageScaleType(ImageScaleType.EXACTLY)//设置图片的缩放模式 .displayer(new RoundedBitmapDisplayer(100))//设置圆角 30代表半径 自定义 .build(); } @Override public int getCount() { return data.size(); } @Override public Object getItem(int i) { return data.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder holder; if(view==null){ view = View.inflate(context,R.layout.item,null); holder = new ViewHolder(); holder.images=view.findViewById(R.id.image_images); holder.subhead=view.findViewById(R.id.text_subhead); holder.price=view.findViewById(R.id.text_price); view.setTag(holder); }else{ holder = (ViewHolder) view.getTag(); } holder.subhead.setText(data.get(i).getSubhead()); holder.price.setText("¥"+data.get(i).getPrice()); ImageLoader.getInstance().displayImage(data.get(i).getImages(),holder.images,options); return view; } class ViewHolder{ ImageView images; TextView subhead; TextView price; } }4.MyApplication异步获取图片的框架封装,另一半在适配器中
package com.example.zuoye0111;
9.网络请求的数据JavaBean建一个类,ALT+S在弹出的对话框中复制进接口请求的数据import android.app.Application; import android.os.Environment; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache; import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import java.io.File; /** * Created by dell on 2018/1/11. */ public class MyApplication extends Application{ @Override public void onCreate() { super.onCreate(); //自定义SD卡缓存目录 1.android默认cache-app被卸载时,缓存的目录一并被删除 2.自定义 File file = new File(Environment.getExternalStorageDirectory().getPath()+"/images"); //1.将Application初始化 进行全局配置 ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this) .memoryCacheExtraOptions(400,700)//缓存图片的最大的长和高 .threadPoolSize(3)//线程池的数量 .threadPriority(4)// .memoryCacheSize(20*1024*1024)//设置内存缓存区大小 .diskCacheSize(80*1024*1024)//设置SD卡缓存区大小 .diskCache(new UnlimitedDiscCache(file))//自定义SD卡缓存目录 .writeDebugLogs()//打印日志内容 .diskCacheFileNameGenerator(new Md5FileNameGenerator())//给缓存的文件名进行MD5加密处理 .build(); ImageLoader.getInstance().init(configuration); } }5.自定义ListView
package com.example.zuoye0111; import android.content.Context; import android.util.AttributeSet; import android.widget.ListView; /** * Created by dell on 2018/1/11. */ public class MyListview extends ListView{ public MyListview(Context context) { super(context); } public MyListview(Context context, AttributeSet attrs) { super(context, attrs); } public MyListview(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int spec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, spec); } }
6.异步请求网络的封装
package com.example.zuoye0111; import android.os.AsyncTask; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; /** * 使用AsyncTask+HttpURLConnection请求数据 * Created by e531 on 2017/10/12. */ public class MyTask extends AsyncTask<String,Void,String> { //申请一个接口类对象 private Icallbacks icallbacks; //将无参构造设置成私有的,使之在外部不能够调用 private MyTask(){} //定义有参构造方法 public MyTask(Icallbacks icallbacks) { this.icallbacks = icallbacks; } @Override protected String doInBackground(String... params) { String str=""; try { //使用HttpUrlConnection URL url=new URL(params[0]); HttpURLConnection connection=(HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setReadTimeout(5000); connection.setConnectTimeout(5000); if(connection.getResponseCode()==200){ InputStream inputStream=connection.getInputStream(); //调用工具类中的静态方法 str=StreamToString.streamToStr(inputStream,"utf-8"); } } catch (MalformedURLException e) { e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } return str; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); //解析,封装到bean,更新ui组件 icallbacks.updateUiByjson(s); } //定义一个接口 public interface Icallbacks{ /** * 根据回传的json字符串,解析并更新页面组件 * @param jsonstr */ void updateUiByjson(String jsonstr); } }7.判断网络是否连接的封装
package com.example.zuoye0111; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; /** * 得到网络状态的工具类 * Created by e531 on 2017/10/16. */ public class NetStateUtil { /* * 判断网络连接是否已开 * true 已打开 false 未打开 * */ public static boolean isConn(Context context){ boolean bisConnFlag=false; ConnectivityManager conManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo network = conManager.getActiveNetworkInfo(); if(network!=null){ bisConnFlag=conManager.getActiveNetworkInfo().isAvailable(); } return bisConnFlag; } /** * 当判断当前手机没有网络时选择是否打开网络设置 * @param context */ public static void showNoNetWorkDlg(final Context context) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setIcon(R.mipmap.ic_launcher) // .setTitle(R.string.app_name) // .setMessage("当前无网络").setPositiveButton("设置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 跳转到系统的网络设置界面 Intent intent = null; // 先判断当前系统版本 if(android.os.Build.VERSION.SDK_INT > 10){ // 3.0以上 intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS); }else{ intent = new Intent(); intent.setClassName("com.android.settings", "com.android.settings.WirelessSettings"); } context.startActivity(intent); } }).setNegativeButton("知道了", null).show(); } }8.流转字符串的封装
package com.example.zuoye0111; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; /** * Created by e531 on 2017/10/12. */ public class StreamToString { public static String streamToStr(InputStream inputStream,String chartSet){ StringBuilder builder=new StringBuilder(); try { BufferedReader br=new BufferedReader(new InputStreamReader(inputStream,chartSet)); String con; while ((con=br.readLine())!=null){ builder.append(con); } br.close(); return builder.toString(); } catch (Exception e) { e.printStackTrace(); } return ""; } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.zuoye0111.MainActivity"> <com.handmark.pulltorefresh.library.PullToRefreshScrollView android:id="@+id/p_sv" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.TabLayout android:id="@+id/my_tab" android:layout_width="match_parent" android:layout_height="50dp"> </android.support.design.widget.TabLayout> <android.support.v4.view.ViewPager android:layout_marginTop="30dp" android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="200dp"> </android.support.v4.view.ViewPager> <com.example.zuoye0111.MyListview android:id="@+id/my_lv" android:layout_marginTop="30dp" android:layout_width="match_parent" android:layout_height="match_parent"> </com.example.zuoye0111.MyListview> </LinearLayout> </com.handmark.pulltorefresh.library.PullToRefreshScrollView> </RelativeLayout>