写两个Base类,方便调用
一个Activity里面调用的:
package com.ang.lianxi;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
public abstract class BaseActivity extends FragmentActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(bindLayout());
initView();
initData();;
bindEvent();
}
public abstract int bindLayout();
public abstract void initView();
public abstract void initData();
public abstract void bindEvent();
}
一个fragment里面调用的:
package com.ang.lianxi;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public abstract class BaseFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(bindLayout(),container,false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initView();
initData();
bindEvent();
}
//绑定视图
protected abstract int bindLayout();
//绑定组件
protected abstract void initView();
//操作数据
protected abstract void initData();
//设置监听
protected abstract void bindEvent();
}
写一个判断有没有网络的方法,在写一个AsynTask请求网络的方法,方便调用!
package com.ang.lianxi.http;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class Http {
//判断有没有网的方法
public static boolean isWorkConnected(Context con){
if(con!=null){
//获取连接管理器
ConnectivityManager manager = (ConnectivityManager) con.getSystemService(Context.CONNECTIVITY_SERVICE);
//获取网络状态
NetworkInfo info = manager.getActiveNetworkInfo();
if(info!=null){
//判断网络是否可用
return info.isAvailable();
}
}
return false;
}
public static void httpAsynTask(String strUrl,final CallBackString backString){
new AsyncTask<String,Integer,String>(){
@Override
protected String doInBackground(String... strings) {
return HttpGet(strings[0]);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//接口回调的方法
backString.getData(s);
}
}.execute(strUrl);
}
//接口
public interface CallBackString{
void getData(String s);
}
public static String HttpGet(String strUrl){
try {
//设置url
URL url=new URL(strUrl);
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
//设置get请求
connection.setRequestMethod("GET");
//设置从主机读取数据超时
connection.setReadTimeout(5000);
//设置连接主机超时时间
connection.setConnectTimeout(5000);
int code = connection.getResponseCode();
if(code==200){
//得到数据
InputStream stream = connection.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(stream,"utf-8"));
//拼接数据
StringBuilder builder=new StringBuilder();
String str="";
while ((str=reader.readLine())!=null){
builder.append(str);
}
//返回数据
return builder.toString();
}
//关闭连接
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
数据库
package com.ang.lianxi.sql;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MySqlite extends SQLiteOpenHelper {
public MySqlite(Context context) {
super(context, "la.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
//你要添加的数据
sqLiteDatabase.execSQL("create table news(id integer primary key autoincrement,name text,tit text,img text)");
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
数据库配合着Dao使用:
这里我只写了两个方法:一个添加、一个查询
package com.ang.lianxi.sql;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class Dao {
private final SQLiteDatabase db;
public Dao(Context con){
MySqlite mySqlite=new MySqlite(con);
db = mySqlite.getWritableDatabase();
}
public long insert(String table, String nullColumnHack, ContentValues values) {
return db.insert(table,nullColumnHack,values);
}
public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
return db.query(table,columns,selection,selectionArgs,groupBy,having,orderBy);
}
}
我用的是ImageLoader加载图片
package com.ang.lianxi.app;
import android.app.Application;
import android.graphics.Bitmap;
import android.os.Environment;
import com.ang.lianxi.R;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.display.CircleBitmapDisplayer;
import java.io.File;
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
String path=Environment.getExternalStorageDirectory().getPath()+"/TuPian";
File file=new File(path);
DisplayImageOptions options=new DisplayImageOptions.Builder()
// 正在加载时显示的占位图
.showImageOnLoading(R.mipmap.zhan)
// 加载失败时显示的占位图
.showImageOnFail(R.mipmap.shibai)
//设置圆形
.displayer(new CircleBitmapDisplayer())
// bitmap的质量,默认为ARGB_8888
.bitmapConfig(Bitmap.Config.ARGB_8888)
.build();
ImageLoaderConfiguration loaderConfiguration=new ImageLoaderConfiguration.Builder(this)
//把我们写的设置添加到构建中
.defaultDisplayImageOptions(options)
.memoryCacheExtraOptions(200, 200)//配置内存缓存图片的尺寸
.memoryCacheSize(2 * 1024 * 1024)//配置内存缓存的大小
.threadPoolSize(3)//配置加载图片的线程数
.threadPriority(1000)//配置线程的优先级
.diskCache(new UnlimitedDiskCache(file))//UnlimitedDiskCache 限制这个图片的缓存路径
.diskCacheFileCount(50)//配置sdcard缓存文件的数量
.diskCacheFileNameGenerator(new Md5FileNameGenerator())//MD5这种方式生成缓存文件的名字
.diskCacheSize(50 * 1024 * 1024)//在sdcard缓存50MB
.build();//完成
//获得实例
ImageLoader imageLoader=ImageLoader.getInstance();
//初始化
imageLoader.init(loaderConfiguration);
}
}
主页面我写的是一个类似于QQ页面的
先看下布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
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=".MainActivity">
<android.support.v4.widget.DrawerLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--主页面-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/frag"
></FrameLayout>
<RadioGroup
android:id="@+id/radi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<RadioButton
android:id="@+id/radio1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:text="列表"
android:background="@drawable/sele"
android:button="@null"
android:textSize="20sp"
android:padding="8dp"
/>
<RadioButton
android:id="@+id/radio2"
android:layout_width="0dp"
android:layout_weight="1"
android:background="@drawable/sele"
android:layout_height="match_parent"
android:gravity="center"
android:text="表格"
android:button="@null"
android:textSize="20sp"
android:padding="8dp"
/>
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_gravity="left"
android:background="#ded3d3"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/tx"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center"
/>
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/list"
></ListView>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
接下来是Activity里面,加一个侧拉页面(侧拉页面 我就随便展示了一个接口数据)
package com.ang.lianxi;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioGroup;
import com.ang.lianxi.adapter.MyActivityAdapter;
import com.ang.lianxi.bean.Datass;
import com.ang.lianxi.bean.NewsBean;
import com.ang.lianxi.frag.FragList;
import com.ang.lianxi.frag.FragNull;
import com.ang.lianxi.http.Http;
import com.google.gson.Gson;
import com.nostra13.universalimageloader.core.ImageLoader;
import java.util.ArrayList;
public class MainActivity extends BaseActivity {
private RadioGroup radi;
private FragList f1;
private FragNull f2;
private ImageView im;
private ListView list;
private String str="http://api.expoon.com/AppNews/getNewsList/type/1/p/1";
@Override
public void initView() {
//找控件
radi = findViewById(R.id.radi);
radi.check(radi.getChildAt(0).getId());
im = findViewById(R.id.tx);
list = findViewById(R.id.list);
String ss="http://image.baidu.com/search/down?tn=download&word=download&ie=utf8&fr=detail&url=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201410%2F05%2F20141005082835_2RTzn.thumb.700_0.jpeg&thumburl=http%3A%2F%2Fimg2.imgtn.bdimg.com%2Fit%2Fu%3D3846895839%2C2711067435%26fm%3D26%26gp%3D0.jpg";
//侧拉的 个人头像设置
ImageLoader.getInstance().displayImage(ss, im);
}
@Override
public int bindLayout() {
return R.layout.activity_main;
}
@Override
public void initData() {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
f1 = new FragList();
f2 = new FragNull();
transaction.add(R.id.frag, f1);
transaction.add(R.id.frag, f2);
transaction.hide(f2).show(f1);
transaction.commit();
Http.httpAsynTask(str, new Http.CallBackString() {
@Override
public void getData(String s) {
if(Http.isWorkConnected(MainActivity.this)){
Gson gson=new Gson();
NewsBean bean = gson.fromJson(s, NewsBean.class);
ArrayList<Datass> data = bean.getData();
list.setAdapter(new MyActivityAdapter(data,MainActivity.this));
}
}
});
}
@Override
public void bindEvent() {
radi.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
FragmentTransaction tt = getSupportFragmentManager().beginTransaction();
switch (i){
case R.id.radio1:
tt.hide(f2).show(f1);
break;
case R.id.radio2:
tt.hide(f1).show(f2);
break;
}
tt.commit();
}
});
}
}
适配器我写的是外部的(这里我用了一个listview多条目),代码如下:
package com.ang.lianxi.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.ang.lianxi.R;
import com.ang.lianxi.bean.Datass;
import com.nostra13.universalimageloader.core.ImageLoader;
import java.util.ArrayList;
public class MyActivityAdapter extends BaseAdapter {
private ArrayList<Datass> arr;
private Context con;
public MyActivityAdapter(ArrayList<Datass> arr, Context con) {
this.arr = arr;
this.con = con;
}
@Override
public int getCount() {
return arr.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public int getViewTypeCount() {
return 4;
}
@Override
public int getItemViewType(int position) {
return position%4;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
switch (getItemViewType(i)){
case 0:
ViewHolder vh;
if(view==null){
view=LayoutInflater.from(con).inflate(R.layout.ce_one, null);
vh=new ViewHolder();
vh.img=view.findViewById(R.id.img);
vh.tit=view.findViewById(R.id.tit);
view.setTag(vh);
}else{
vh= (ViewHolder) view.getTag();
}
vh.tit.setText(arr.get(i).getNews_title());
ImageLoader.getInstance().displayImage(arr.get(i).getPic_url(),vh.img);
break;
case 1:
ViewHolder1 vh1;
if(view==null){
view=LayoutInflater.from(con).inflate(R.layout.ce_two, null);
vh1=new ViewHolder1();
vh1.img=view.findViewById(R.id.img);
vh1.tit=view.findViewById(R.id.tit);
view.setTag(vh1);
}else{
vh1= (ViewHolder1) view.getTag();
}
vh1.tit.setText(arr.get(i).getNews_title());
ImageLoader.getInstance().displayImage(arr.get(i).getPic_url(),vh1.img);
break;
case 2:
ViewHolder2 vh2;
if(view==null){
view=LayoutInflater.from(con).inflate(R.layout.ce_three, null);
vh2=new ViewHolder2();
vh2.tit=view.findViewById(R.id.tit);
vh2.img=view.findViewById(R.id.img);
view.setTag(vh2);
}else{
vh2= (ViewHolder2) view.getTag();
}
vh2.tit.setText(arr.get(i).getNews_title());
ImageLoader.getInstance().displayImage(arr.get(i).getPic_url(),vh2.img);
break;
case 3:
ViewHolder3 vh3;
if(view==null){
view=LayoutInflater.from(con).inflate(R.layout.ce_four, null);
vh3=new ViewHolder3();
vh3.tit=view.findViewById(R.id.tit);
vh3.img=view.findViewById(R.id.img);
view.setTag(vh3);
}else{
vh3= (ViewHolder3) view.getTag();
}
vh3.tit.setText(arr.get(i).getNews_title());
ImageLoader.getInstance().displayImage(arr.get(i).getPic_url(),vh3.img);
break;
}
return view;
}
static class ViewHolder{
ImageView img;
TextView tit;
}
static class ViewHolder1{
ImageView img;
TextView tit;
}
static class ViewHolder2{
ImageView img;
TextView tit;
}
static class ViewHolder3{
ImageView img;
TextView tit;
}
}
接下来是fragment里面的啦
首先布局:
自己提前导一个PullToRefresh 然后把PullToRefresh和自己的项目关联起来
<?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">
<com.handmark.pulltorefresh.library.PullToRefreshListView
android:id="@+id/pull"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
布局完了,就是主要的代码啦
package com.ang.lianxi.frag;
import android.content.ContentValues;
import android.database.Cursor;
import android.widget.ListView;
import android.widget.Toast;
import com.ang.lianxi.BaseFragment;
import com.ang.lianxi.R;
import com.ang.lianxi.adapter.MyAdapter;
import com.ang.lianxi.bean.Datas;
import com.ang.lianxi.bean.JsonBean;
import com.ang.lianxi.http.Http;
import com.ang.lianxi.sql.Dao;
import com.google.gson.Gson;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import java.util.ArrayList;
public class FragList extends BaseFragment {
private PullToRefreshListView listv;
private String str="http://www.xieast.com/api/news/news.php?page=1";
private ArrayList<Datas> data;
private MyAdapter adapter;
private Dao dao;
@Override
protected int bindLayout() {
return R.layout.frag_list;
}
@Override
protected void initView() {
//找控件
listv = getActivity().findViewById(R.id.pull);
//设置模式 BOTH:支持上拉加载 下拉刷新 PULL_FROM_END:仅支持加载更多 PULL_FROM_START:下拉刷新
listv.setMode(PullToRefreshBase.Mode.BOTH);
//设置刷新的时候可以滑动
listv.setScrollingWhileRefreshingEnabled(true);
dao = new Dao(getActivity());
}
@Override
protected void initData() {
//判断有没有网络
boolean workConnected = Http.isWorkConnected(getActivity());
if(workConnected){
//有就加载数据
Http.httpAsynTask(str, new Http.CallBackString() {
@Override
public void getData(String s) {
Gson gson=new Gson();
JsonBean bean = gson.fromJson(s, JsonBean.class);
data = bean.getData();
//判断有没有数据 有数据就不添加
if(dao.query("news",null,null,null,null,null,null).moveToFirst()){
}else{
//如果没有就添加
for (Datas beana : data){
ContentValues values = new ContentValues();
values.put("tit", beana.getTitle());
values.put("name", beana.getAuthor_name());
values.put("img", beana.getThumbnail_pic_s());
dao.insert("news", null, values);
}
}
//适配器
adapter = new MyAdapter(data,getActivity());
listv.setAdapter(adapter);
}
});
}else {
//没有 就查找数据库有没有 数据库有加载数据库
Cursor cursor = dao.query("news", null, null, null, null, null, null);
data=new ArrayList<>();
if(cursor.moveToFirst()){
do {
//name text,tit text,img text
String name = cursor.getString(cursor.getColumnIndex("name"));
String tit = cursor.getString(cursor.getColumnIndex("tit"));
String img = cursor.getString(cursor.getColumnIndex("img"));
data.add(new Datas(name,tit,img));
}while (cursor.moveToNext());
}
cursor.close();
Toast.makeText(getActivity(),"没有网络",Toast.LENGTH_LONG).show();
//适配器
adapter=new MyAdapter(data,getActivity());
listv.setAdapter(adapter);
}
}
@Override
protected void bindEvent() {
listv.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
@Override
public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
//判断有没有网络
if(Http.isWorkConnected(getActivity())){
//下拉刷新
Http.httpAsynTask(str, new Http.CallBackString() {
@Override
public void getData(String s) {
//解析
Gson gson=new Gson();
JsonBean bean = gson.fromJson(s, JsonBean.class);
data = bean.getData();
adapter=new MyAdapter(data,getActivity());
listv.setAdapter(adapter);
listv.onRefreshComplete();
}
});
}else {
Toast.makeText(getActivity(),"没有网络",Toast.LENGTH_LONG).show();
}
}
@Override
public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
//判断网络状态
if(Http.isWorkConnected(getActivity())){
//上拉加载
Http.httpAsynTask(str, new Http.CallBackString() {
@Override
public void getData(String s) {
//解析
Gson gson=new Gson();
JsonBean bean = gson.fromJson(s, JsonBean.class);
ArrayList<Datas> datas = bean.getData();
data.addAll(datas);
adapter.notifyDataSetChanged();
// 当列表被刷新时,调用onRefreshComplete
listv.onRefreshComplete();
}
});
}else {
Toast.makeText(getActivity(),"没有网络",Toast.LENGTH_LONG).show();
}
}
});
}
}
fragment用到的适配器
package com.ang.lianxi.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.ang.lianxi.R;
import com.ang.lianxi.bean.Datas;
import com.nostra13.universalimageloader.core.ImageLoader;
import java.util.ArrayList;
public class MyAdapter extends BaseAdapter {
private ArrayList<Datas> arr;
private Context con;
public MyAdapter(ArrayList<Datas> arr, Context con) {
this.arr = arr;
this.con = con;
}
@Override
public int getCount() {
return arr.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public int getViewTypeCount() {
return 3;
}
@Override
public int getItemViewType(int position) {
return position%3;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
switch (getItemViewType(i)){
case 0:
ViewHolder vh;
if(view==null){
view=LayoutInflater.from(con).inflate(R.layout.item_one, null);
vh=new ViewHolder();
vh.img=view.findViewById(R.id.img);
vh.tit=view.findViewById(R.id.tit);
view.setTag(vh);
}else{
vh= (ViewHolder) view.getTag();
}
vh.tit.setText(arr.get(i).getTitle());
ImageLoader.getInstance().displayImage(arr.get(i).getThumbnail_pic_s(),vh.img);
break;
case 1:
ViewHolder1 vh1;
if(view==null){
view=LayoutInflater.from(con).inflate(R.layout.item_two, null);
vh1=new ViewHolder1();
vh1.img=view.findViewById(R.id.img);
vh1.name=view.findViewById(R.id.name);
vh1.tit=view.findViewById(R.id.tit);
view.setTag(vh1);
}else{
vh1= (ViewHolder1) view.getTag();
}
vh1.tit.setText(arr.get(i).getTitle());
vh1.name.setText(arr.get(i).getAuthor_name());
ImageLoader.getInstance().displayImage(arr.get(i).getThumbnail_pic_s(),vh1.img);
break;
case 2:
ViewHolder2 vh2;
if(view==null){
view=LayoutInflater.from(con).inflate(R.layout.item_three, null);
vh2=new ViewHolder2();
vh2.tit=view.findViewById(R.id.tit);
view.setTag(vh2);
}else{
vh2= (ViewHolder2) view.getTag();
}
vh2.tit.setText(arr.get(i).getTitle());
break;
}
return view;
}
static class ViewHolder{
ImageView img;
TextView tit;
}
static class ViewHolder1{
ImageView img;
TextView tit,name;
}
static class ViewHolder2{
TextView tit;
}
}
如果里面有CheckBox 避免和点击事件冲突
<!--android:focusable="false"避免冲突-->
<CheckBox
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textSize="20sp"
android:focusable="false"
android:text="点击勾选"
/>
最后记住要写网络权限、ImageLoader也要注册一下
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:name=".app.App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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>