权限
useLibrary 'org.apache.http.legacy'
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++main
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.hello.myappzuoye.MainActivity"> <android.support.design.widget.TabLayout android:id="@+id/tl_tab" android:layout_width="match_parent" android:layout_height="40dp" app:tabGravity="center" app:tabIndicatorColor="@color/colorAccent" app:tabMode="scrollable" app:tabSelectedTextColor="@color/colorPrimaryDark" app:tabTextColor="@color/colorPrimary" /> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v4.view.ViewPager> </LinearLayout> ++++++++++++++++++++++++++++++++++++++++++++++fragment_listview<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.handmark.pulltorefresh.library.PullToRefreshListView xmlns:ptr="http://schemas.android.com/apk/res-auto" android:layout_height="match_parent" android:layout_width="match_parent" android:id="@+id/refresh_list_view" ptr:ptrDrawable="@drawable/default_ptr_flip" ptr:ptrAnimationStyle="flip" ptr:ptrHeaderBackground="#383838" ptr:ptrHeaderTextColor="#FFFFFF" > </com.handmark.pulltorefresh.library.PullToRefreshListView> </LinearLayout>++++++++++++++++++++++++++++++++++++++++++++++++++++++item_gridviewlayout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.handmark.pulltorefresh.library.PullToRefreshGridView xmlns:ptr="http://schemas.android.com/apk/res-auto" android:layout_height="match_parent" android:layout_width="match_parent" android:numColumns="2" android:id="@+id/refresh_grid_view" ptr:ptrDrawable="@drawable/default_ptr_flip" ptr:ptrAnimationStyle="flip" ptr:ptrHeaderBackground="#383838" ptr:ptrHeaderTextColor="#FFFFFF" > </com.handmark.pulltorefresh.library.PullToRefreshGridView> </LinearLayout>++++++++++++++++++++++++++++++++++++++++++++++++item_img_layout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:padding="10dp" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text_title" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" /> <ImageView android:id="@+id/image_view" android:layout_width="100dp" android:layout_height="100dp" /> </LinearLayout>++++++++++++++++++++++++++++++++++++++++++++++++++++item_img_layout2
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="10dp" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image_view" android:layout_width="100dp" android:layout_height="100dp" /> <TextView android:id="@+id/text_title" android:layout_width="wrap_content" android:layout_weight="1" android:layout_height="wrap_content" /> </LinearLayout>+++++++++++++++++++++++++++++++++++++++++++++++item_text_layout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="10dp" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image_view" android:layout_width="100dp" android:layout_height="100dp" /> <TextView android:id="@+id/text_title" android:layout_width="wrap_content" android:layout_weight="1" android:layout_height="wrap_content" /> </LinearLayout>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/** * 使用pullToRefresh进行下拉刷新和上拉加载 * 1.去github上下载压缩包,解压出来,把library复制出来改名,路径最好不要有中文 * 2.使用import moundle导进这个库文件,添加库文件的依赖 * 3.此时左下角可能会报错,只需要点击install...去下载16版本的sdk,还需要下载19版本的buildTools * * 查看代码可以看到 * PullToRefreshListView可以刷新的listView控件....间接继承了LinearLayout,是一个自定义的listView * PullToRefreshGridView可以刷新的GridView控件 * PullToRefreshExpandableListView可以刷新的二级列表控件 * PullToRefreshScrollView可以刷新的ScrollView控件 * PullToRefreshWebView可以刷新的WebView控件 */ public class MainActivity extends AppCompatActivity { private TabLayout tabLayout; private ViewPager viewPager; private List<String> list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tabLayout = (TabLayout) findViewById(R.id.tl_tab); viewPager = (ViewPager) findViewById(R.id.view_pager); list = new ArrayList<>(); list.add("推荐"); list.add("热点"); list.add("北京"); //1.设置适配器...fragmnePagerAdapter....getChildFragmentManager...getFragmentManager viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { //2.重写方法...返回的是viewPager当前页的标题 @Override public CharSequence getPageTitle(int position) { return list.get(position); } @Override public Fragment getItem(int position) {//0...listView,1...gridView,2..scrollView Fragment fragment = null; switch (position){ case 0: fragment = new FragmentListView(); break; case 1: fragment = new FragmentGridView(); break; case 2: fragment = new FragmentScrollView(); break; default: break; } return fragment; } @Override public int getCount() { return list.size(); } }); //3.tablayout与viewPager关联使用 tabLayout.setupWithViewPager(viewPager); } }+++++++++++++++++++++++++++++++++++++++++++++++++++++++++public interface JsonCallBack { public void getJsonString(String json); }+++++++++++++++++++++++++++++++++++++++++++++++++public class BaseApplication extends Application{ @Override public void onCreate() { super.onCreate(); //初始化 ImageLoaderUtil.init(this); } }++++++++++++++++++++++++++++++++++++++++++++++++++public class ImageLoaderUtil { public static void init(Context context){ File cacheDir = StorageUtils.getCacheDirectory(context); //缓存文件夹路径 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) .threadPoolSize(3) // default 线程池内加载的数量 .threadPriority(Thread.NORM_PRIORITY - 2) // default 设置当前线程的优先级 .tasksProcessingOrder(QueueProcessingType.FIFO) // default .denyCacheImageMultipleSizesInMemory() .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通过自己的内存缓存实现 .memoryCacheSize(2 * 1024 * 1024) // 内存缓存的最大值 .memoryCacheSizePercentage(13) // default .diskCache(new UnlimitedDiskCache(cacheDir)) // default 可以自定义缓存路径 .diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值 .diskCacheFileCount(100) // 可以缓存的文件数量 // default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密 .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default .writeDebugLogs() // 打印debug log .build(); //开始构建 ImageLoader.getInstance().init(config); } public static DisplayImageOptions gettupianyuanjiao(){ DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.mipmap.ic_launcher) // 设置图片下载期间显示的图片 .showImageForEmptyUri(R.mipmap.ic_launcher) // 设置图片Uri为空或是错误的时候显示的图片 .showImageOnFail(R.mipmap.ic_launcher) // 设置图片加载或解码过程中发生错误显示的图片 .resetViewBeforeLoading(true) // default 设置图片在加载前是否重置、复位 .cacheInMemory(true) // default 设置下载的图片是否缓存在内存中 .cacheOnDisk(true) // default 设置下载的图片是否缓存在SD卡中 .considerExifParams(true) // default .imageScaleType(ImageScaleType.EXACTLY_STRETCHED) // default 设置图片以如何的编码方式显示 .bitmapConfig(Bitmap.Config.RGB_565) // default 设置图片的解码类型 .displayer(new RoundedBitmapDisplayer(10)) // default 还可以设置圆角图片new RoundedBitmapDisplayer(20) .build(); return options; } }+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++public class NetDataUtil { public static void getData(final String path, Context context, final JsonCallBack callBack){ if (NetWorkUtil.isConn(context)){ AsyncTask<Void, Void, String> asyncTask = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { URL url = new URL(path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setReadTimeout(5000); connection.setConnectTimeout(5000); int responseCode = connection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = connection.getInputStream(); String json = StringUtil.streamToString(inputStream,"utf-8"); return json; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String s) { //通过接口把json格式的字符串传递回去.... callBack.getJsonString(s); } }; asyncTask.execute(); }else { NetWorkUtil.showNoNetWorkDlg(context); } } }+++++++++++++++++++++++++++++++++++++++++++++++++public class NetWorkUtil { /** * 这个方法是判断网络状态是否可用的 * @param context * @return */ public static boolean isConn(Context context){ boolean bisConnFlag=false; //1.获取网络连接的管理对象 ConnectivityManager conManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); //2.通过管理者对象拿到网络的信息 NetworkInfo network = conManager.getActiveNetworkInfo(); if(network!=null){ //3.网络状态是否可用的返回值 bisConnFlag=network.isAvailable(); } return bisConnFlag; } /** * 如果没有网络 弹出dialog对话框,,,是否进入设置网络的页面 * @param context */ public static void showNoNetWorkDlg(final Context context) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setIcon(R.mipmap.ic_launcher) // .setTitle("警告") // .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(); } }++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++public class StringUtil { public static String streamToString(InputStream inputStream, String charset) { try { InputStreamReader inputStreamReader = new InputStreamReader(inputStream,charset); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String s = null; StringBuilder builder = new StringBuilder(); while ((s = bufferedReader.readLine()) != null){ builder.append(s); } bufferedReader.close(); return builder.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } }+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++public class FragmentGridView extends Fragment { private PullToRefreshGridView refreshGridView; private int page_num = 1; private List<DataDataBean.ResultsBean> list = new ArrayList<>();//记录当前展示的所有数据 private ILoadingLayout startLabels; private GridViewAdapter gridViewAdapter; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.item_gridviewlayout,container,false); refreshGridView = view.findViewById(R.id.refresh_grid_view); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //1.默认的获取第一页的数据,然后设置适配器 getDataFromNet(); //2.设置可以刷新的模式 refreshGridView.setMode(PullToRefreshBase.Mode.BOTH); //3.设置刷新的时候展示的文字(状态) startLabels = refreshGridView.getLoadingLayoutProxy(true, false); startLabels.setPullLabel("下拉刷新"); startLabels.setRefreshingLabel("正在刷新..."); startLabels.setReleaseLabel("放开刷新"); ILoadingLayout endLabels = refreshGridView.getLoadingLayoutProxy(false, true); endLabels.setPullLabel("上拉刷新"); endLabels.setRefreshingLabel("正在载入..."); endLabels.setReleaseLabel("放开刷新..."); //4.设置下拉和上拉刷新的监听事件 refreshGridView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<GridView>() { @Override public void onPullDownToRefresh(PullToRefreshBase<GridView> refreshView) { //下拉刷新....请求第一页的数据,清空之前的数据,然后再添加设置适配器 getRefreshData(); } @Override public void onPullUpToRefresh(PullToRefreshBase<GridView> refreshView) { //上拉刷新/加载...加载的时候页数++ page_num++; getDataFromNet(); } }); } /** * 下拉刷新获取数据 */ private void getRefreshData() { NetDataUtil.getData("http://gank.io/api/data/Android/10/1", getActivity(), new JsonCallBack() { @Override public void getJsonString(String json) { //解析 Gson gson = new Gson(); DataDataBean dataDataBean = gson.fromJson(json, DataDataBean.class); //先清空一下数据 list.clear(); //添加到集合的最前边,,,,(0,,,,) list.addAll(0,dataDataBean.getResults()); //设置适配器 setAdapter(); //设置适配器之后停止刷新的操作 refreshGridView.onRefreshComplete(); //可以设置刷新的时间.... startLabels.setLastUpdatedLabel("上次更新时间:"+new SimpleDateFormat("HH:mm").format(new Date(System.currentTimeMillis())));//last最近的,最后一次update修改/更新 } }); } /** * 刚开始进入页面获取网络数据....还可以作为上拉加载获取数据的操作 * * */ private void getDataFromNet() { //第一个参数是接口,第二个上下文,第三个回调json数据 NetDataUtil.getData("http://gank.io/api/data/Android/10/"+page_num, getActivity(), new JsonCallBack() { @Override public void getJsonString(String json) { //解析 Gson gson = new Gson(); DataDataBean dataDataBean = gson.fromJson(json, DataDataBean.class); //往后面添加... list.addAll(dataDataBean.getResults()); //设置适配器 setAdapter(); //停止刷新 refreshGridView.onRefreshComplete(); } }); } /** * 设置适配器的方法 */ private void setAdapter() { if (gridViewAdapter == null){ gridViewAdapter = new GridViewAdapter(getActivity(),list); refreshGridView.setAdapter(gridViewAdapter); }else { gridViewAdapter.notifyDataSetChanged(); } } }++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++public class FragmentListView extends Fragment { private PullToRefreshListView refreshListView; private List<DataDataBean.ResultsBean> list = new ArrayList<>(); private MyAdapter myAdapter; private int page_num = 1; private ILoadingLayout startLabels; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_listview_layout,container,false); refreshListView = view.findViewById(R.id.refresh_list_view); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //1.设置listView的适配器 getDataFromNet(); //2.设置刷新模式 /*设置pullToRefreshListView的刷新模式,BOTH代表支持上拉和下拉,PULL_FROM_END代表上拉,PULL_FROM_START代表下拉 */ refreshListView.setMode(PullToRefreshBase.Mode.BOTH); //3.通过getLoadingLayoutProxy 方法来指定上拉和下拉时显示的状态的区别(也就是设置向下拉的时候头部里面显示的文字) //此时这里设置的是下拉刷新的时候显示的文字,所以第一个设置true表示现在是刷新,第二个设置为false final ILoadingLayout startLabels = refreshListView.getLoadingLayoutProxy(true, false); startLabels.setPullLabel("下拉刷新"); startLabels.setRefreshingLabel("正在刷新..."); startLabels.setReleaseLabel("放开刷新"); ILoadingLayout endLabels = refreshListView.getLoadingLayoutProxy(false, true); endLabels.setPullLabel("上拉刷新"); endLabels.setRefreshingLabel("正在载入..."); endLabels.setReleaseLabel("放开刷新..."); //4.设置监听事件 /** * 如果Mode设置成Mode.BOTH,需要设置刷新Listener为OnRefreshListener2,并实现onPullDownToRefresh()、 * onPullUpToRefresh()两个方法。 如果Mode设置成Mode.PULL_FROM_START或Mode.PULL_FROM_END,需要设置刷新Listener为OnRefreshListener, 同时实现onRefresh()方法。 当然也可以设置为OnRefreshListener2,但是Mode.PULL_FROM_START的时候只调用onPullDownToRefresh()方法, Mode.PULL_FROM_END的时候只调用onPullUpToRefresh()方法 */ refreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() { //下拉刷新的时候调用的方法....请求第一页的数据,清空之前的数据,然后再添加设置适配器 @Override public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) { NetDataUtil.getData("http://gank.io/api/data/Android/10/1", getActivity(), new JsonCallBack() { @Override public void getJsonString(String json) { //解析 Gson gson = new Gson(); DataDataBean dataDataBean = gson.fromJson(json, DataDataBean.class); //先清空一下数据 list.clear(); //添加到集合的最前边,,,,(0,,,,) list.addAll(0,dataDataBean.getResults()); //设置适配器 setAdapter(); //设置适配器之后停止刷新的操作 refreshListView.onRefreshComplete(); //可以设置刷新的时间.... // startLabels.setLastUpdatedLabel("上次更新时间:"+new SimpleDateFormat("HH:mm").format(new Date(System.currentTimeMillis())));//last最近的,最后一次update修改/更新 } }); } //上拉刷新的时候调用的方法..page++,然后在请求数据 @Override public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) { page_num++; getDataFromNet(); } }); } /** * 获取网络数据 */ private void getDataFromNet() { //第一个参数是接口,第二个上下文,第三个回调json数据 NetDataUtil.getData("http://gank.io/api/data/Android/10/"+page_num, getActivity(), new JsonCallBack() { @Override public void getJsonString(String json) { //解析 Gson gson = new Gson(); DataDataBean dataDataBean = gson.fromJson(json, DataDataBean.class); //往后面添加... list.addAll(dataDataBean.getResults()); //设置适配器 setAdapter(); //停止刷新 refreshListView.onRefreshComplete(); } }); } private void setAdapter() { if (myAdapter == null){ myAdapter = new MyAdapter(getActivity(),list); refreshListView.setAdapter(myAdapter); }else { myAdapter.notifyDataSetChanged(); } } }++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++public class FragmentScrollView extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return super.onCreateView(inflater, container, savedInstanceState); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } }++++++++++++++++++++++++++++++++++++++++++++++++++++++public class GridViewAdapter extends BaseAdapter{ Context context; List<DataDataBean.ResultsBean> list; public GridViewAdapter(Context context, List<DataDataBean.ResultsBean> list) { this.context = context; this.list = list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int i) { return list.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_img_layout2,null); holder = new ViewHolder(); holder.textView = view.findViewById(R.id.text_title); holder.imageView = view.findViewById(R.id.image_view); view.setTag(holder); }else { holder = (ViewHolder) view.getTag(); } holder.textView.setText(list.get(i).getDesc()); //展示图片的时候,,,getImages这个集合有的有,有的为空...所以要进行.判断 if (list.get(i).getImages() != null){ //此时加载图片显示 ImageLoader.getInstance().displayImage(list.get(i).getImages().get(0),holder.imageView, ImageLoaderUtil.gettupianyuanjiao()); } return view; } private class ViewHolder{ TextView textView; ImageView imageView; } }+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++public class MyAdapter extends BaseAdapter { Context context; List<DataDataBean.ResultsBean> list; public MyAdapter(Context context, List<DataDataBean.ResultsBean> list) { this.context = context; this.list = list; } private int TEXT_ONLY = 0; private int IMAGE_TEXT = 1; @Override public int getCount() { return list.size(); } @Override public Object getItem(int i) { return list.get(i); } @Override public long getItemId(int i) { return i; } @Override public int getViewTypeCount() { return 2; } @Override public int getItemViewType(int position) { if (list.get(position).getImages() != null){ return IMAGE_TEXT; } return TEXT_ONLY; } @Override public View getView(int i, View view, ViewGroup viewGroup) { if (getItemViewType(i) == TEXT_ONLY){ TextHolder holder; if (view == null){ view = View.inflate(context, R.layout.item_text_layout,null); holder = new TextHolder(); holder.textView = view.findViewById(R.id.text_title); view.setTag(holder); }else { holder = (TextHolder) view.getTag(); } holder.textView.setText(list.get(i).getDesc()); }else if (getItemViewType(i)==IMAGE_TEXT){ ImageHolder holder; if (view == null){ view = View.inflate(context, R.layout.item_img_layout,null); holder = new ImageHolder(); holder.textView = view.findViewById(R.id.text_title); holder.imageView = view.findViewById(R.id.image_view); view.setTag(holder); }else { holder = (ImageHolder) view.getTag(); } //图片 holder.textView.setText(list.get(i).getDesc()); ImageLoader.getInstance().displayImage(list.get(i).getImages().get(0),holder.imageView, ImageLoaderUtil.gettupianyuanjiao()); } return view; } private class TextHolder{ TextView textView; } private class ImageHolder{ TextView textView; ImageView imageView; } }