实现如图所示效果,实现左侧滑动侧滑效果,首页面显示新闻数据,新闻可以实现上拉下拉效果,根据图片的有无实现多条目加载,使用Universal-Image-Loader进行全局配置并将图片缓存到本地SD卡下,接口地址如下,每次加载更多时startNum值加20:http://www.93.gov.cn/93app/data.do?channelId=0&startNum=0
1.MainActivity
package com.example.yuekaomoni0116; import android.support.design.widget.TabLayout; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ListView; import android.widget.ScrollView; import com.example.yuekaomoni0116.adapter.MyAdapter; import com.example.yuekaomoni0116.data.RequestData; import com.example.yuekaomoni0116.util.MyTask; import com.example.yuekaomoni0116.util.NetStateUtil; import com.google.gson.Gson; import com.handmark.pulltorefresh.library.PullToRefreshBase; import com.handmark.pulltorefresh.library.PullToRefreshScrollView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private PullToRefreshScrollView scrollView; private ListView listView; private TabLayout tabLayout; private List<String> list; private int index=20; private String url = "http://www.93.gov.cn/93app/data.do?channelId=0&startNum=0"; private List<RequestData.DataBean> data=new ArrayList<>(); private MyAdapter myAdapter; private int type=1;//1.刷新。2.加载 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //找到资源控件的ID tabLayout = findViewById(R.id.my_tab); scrollView = findViewById(R.id.my_psv); listView = findViewById(R.id.my_list); //添加菜单栏数据 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")); tabLayout.addTab(tabLayout.newTab().setText("月考6")); tabLayout.addTab(tabLayout.newTab().setText("月考7")); tabLayout.addTab(tabLayout.newTab().setText("月考8")); tabLayout.addTab(tabLayout.newTab().setText("月考9")); //初始化数据 initData(); //网络请求 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 requestData = gson.fromJson(jsonstr, RequestData.class); //下拉刷新时,删除原集合中的数据,重新查新数据 if(type==1){ data.clear(); } //将所有数据添加入集合 data.addAll(requestData.getData()); //设置适配器 setAdater(); } }); myTask.execute(url);//执行url } } private void setAdater() { if(myAdapter==null){ myAdapter = new MyAdapter(MainActivity.this, data); listView.setAdapter(myAdapter); }else{ myAdapter.notifyDataSetChanged(); } } private void initData() { scrollView.setMode(PullToRefreshBase.Mode.BOTH); scrollView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ScrollView>() { @Override//下拉刷新 public void onPullDownToRefresh(PullToRefreshBase<ScrollView> pullToRefreshBase) { type=1; url = "http://www.93.gov.cn/93app/data.do?channelId=0&startNum=0"; requestNetData(); //关闭头尾布局 scrollView.onRefreshComplete(); } @Override//上拉加载 public void onPullUpToRefresh(PullToRefreshBase<ScrollView> pullToRefreshBase) { type=2; index+=20; url = "http://www.93.gov.cn/93app/data.do?channelId=0&startNum="+index; requestNetData(); //关闭头尾布局 scrollView.onRefreshComplete(); } }); } }
2.布局文件
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout 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.yuekaomoni0116.MainActivity"> <RelativeLayout 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" app:tabGravity="center" app:tabIndicatorColor="#fff" app:tabMode="scrollable" app:tabSelectedTextColor="#f89" app:tabTextColor="@color/colorPrimary"> </android.support.design.widget.TabLayout> <com.handmark.pulltorefresh.library.PullToRefreshScrollView android:id="@+id/my_psv" android:layout_below="@id/my_tab" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.yuekaomoni0116.zidingyi.MyListview android:id="@+id/my_list" android:layout_width="match_parent" android:layout_height="match_parent"> </com.example.yuekaomoni0116.zidingyi.MyListview> </com.handmark.pulltorefresh.library.PullToRefreshScrollView> </RelativeLayout> <RelativeLayout android:layout_width="200dp" android:layout_height="match_parent" android:background="#f89" android:layout_gravity="start"> <ImageView android:layout_width="100dp" android:layout_height="100dp" android:src="@mipmap/ic_launcher"/> </RelativeLayout> </android.support.v4.widget.DrawerLayout>3.Adapter:实现数据的适配器
package com.example.yuekaomoni0116.adapter; 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.example.yuekaomoni0116.R; import com.example.yuekaomoni0116.data.RequestData; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import java.util.List; public class MyAdapter extends BaseAdapter{ private Context context; private List<RequestData.DataBean> data; private int YOU_IMG=0; private int WU_IMG=1; private DisplayImageOptions options; public MyAdapter(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)//设置图片色彩模式 .imageScaleType(ImageScaleType.EXACTLY)//设置图片的缩放模式===imageView,,ScaleType //.displayer(new RoundedBitmapDisplayer(50))//设置图片圆角显示 弧度 .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 int getViewTypeCount() { return 2; } @Override public int getItemViewType(int position) { String img = data.get(position).getIMAGEURL(); if(img!=null){ return YOU_IMG; }else{ return WU_IMG; } } @Override public View getView(int i, View view, ViewGroup viewGroup) { int type = getItemViewType(i); if(type==WU_IMG){ ViewHolder holder; if(view==null){ view=View.inflate(context, R.layout.item,null); holder = new ViewHolder(); holder.title=view.findViewById(R.id.text_title); view.setTag(holder); }else{ holder = (ViewHolder) view.getTag(); } holder.title.setText(data.get(i).getTITLE()); return view; }else{ ViewHolder2 holder2; if(view==null){ view=View.inflate(context, R.layout.item2,null); holder2 = new ViewHolder2(); holder2.title2=view.findViewById(R.id.text_title2); holder2.imgurl=view.findViewById(R.id.img_url); view.setTag(holder2); }else{ holder2 = (ViewHolder2) view.getTag(); } holder2.title2.setText(data.get(i).getTITLE()); ImageLoader.getInstance().displayImage(data.get(i).getIMAGEURL(),holder2.imgurl,options); return view; } } class ViewHolder{ TextView title; } class ViewHolder2{ TextView title2; ImageView imgurl; } }4.MyApplication:异步获取图片的框架
package com.example.yuekaomoni0116.util; import android.app.Application; 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; public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); //需要识记的是以下几个参数: File cacheFile=getExternalCacheDir(); ImageLoaderConfiguration config=new ImageLoaderConfiguration.Builder(this) .memoryCacheExtraOptions(480, 800)//缓存图片最大的长和宽 .threadPoolSize(2)//线程池的数量 .threadPriority(4) .memoryCacheSize(2*1024*1024)//设置内存缓存区大小 .diskCacheSize(20*1024*1024)//设置sd卡缓存区大小 .diskCache(new UnlimitedDiscCache(cacheFile))//自定义缓存目录 .writeDebugLogs()//打印日志内容 .diskCacheFileNameGenerator(new Md5FileNameGenerator())//给缓存的文件名进行md5加密处理 .build(); ImageLoader.getInstance().init(config); } }5.MyTask:解析JSON串的方法
package com.example.yuekaomoni0116.util; 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); } }6.NetStateUtil:判断网络是否存在的方法
package com.example.yuekaomoni0116.util; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import com.example.yuekaomoni0116.R; /** * 得到网络状态的工具类 * 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(); } }7.StreamToString:流转为字符串的方法
package com.example.yuekaomoni0116.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; /** * 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 ""; } }8.多条目实现布局<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <TextView android:id="@+id/text_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="北京:凝心齐聚力 扬帆新航程"/> </LinearLayout><?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <TextView android:id="@+id/text_title2" android:layout_width="280dp" android:layout_height="wrap_content" android:text="北京:凝心齐聚力 扬帆新航程"/> <ImageView android:id="@+id/img_url" android:layout_width="80dp" android:layout_height="80dp" android:layout_toRightOf="@id/text_title2" android:layout_alignParentRight="true" android:src="@mipmap/ic_launcher"/> </RelativeLayout>9.清单文件权限配置<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/>android:name=".util.MyApplication"