///M层
public class BeanModel { public void getData(String getUrl, Map<String,String> param,final ResponseCallback responseCallback){ OkhttpUtils.getInstance().postData(getUrl, param,new OkhttpUtils.ICallback() { @Override public void success(String result) { responseCallback.success(result); } @Override public void fail(String msg) { responseCallback.fail(msg); } }); } public interface ResponseCallback{ void success(String string); void fail(String msg); } }
/V层
public interface IView { void success(Bean bean); }
//P层
public class BeanPresenter { private IView iView; private BeanModel model; public BeanPresenter(IView iView){ model=new BeanModel(); attach(iView); } public void attach(IView iView) { this.iView=iView; } public void getData(String getUrl, Map<String,String> maps){ model.getData(getUrl,maps, new BeanModel.ResponseCallback() { @Override public void success(String result) { if (!TextUtils.isEmpty(result)){ String s=result.replace("null(","") .replace(")",""); Bean bean=new Gson().fromJson(s,Bean.class); iView.success(bean); } } @Override public void fail(String msg) { } }); } public void detach(){ this.iView=null; } }
/utils
/Okhttp
public class OkhttpUtils { public static OkhttpUtils okhttpUtils; private OkHttpClient okHttpClient; private Handler handler; private OkhttpUtils(){ okHttpClient=new OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); handler=new Handler(); } public static OkhttpUtils getInstance(){ if (okhttpUtils==null){ okhttpUtils=new OkhttpUtils(); } return okhttpUtils; } //get public void getData(String url,final ICallback callback){ final Request request=new Request.Builder() .url(url).build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { if (callback!=null){ handler.post(new Runnable() { @Override public void run() { callback.fail("请求失败"); } }); } } @Override public void onResponse(Call call, Response response) throws IOException { if (callback!=null){ if (response.isSuccessful()&&response.code()==200){ final String result=response.body().string(); handler.post(new Runnable() { @Override public void run() { callback.success(result); } }); } } } }); } //post public void postData(String url, Map<String,String>params,final ICallback callback){ FormBody.Builder builder=new FormBody.Builder(); for (Map.Entry<String,String>bean:params.entrySet()){ builder.add(bean.getKey(),bean.getValue()); } final Request request=new Request.Builder() .url(url).post(builder.build()).build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { if (callback!=null){ handler.post(new Runnable() { @Override public void run() { callback.fail("请求失败"); } }); } } @Override public void onResponse(Call call, Response response) throws IOException { if (callback!=null){ if (response.isSuccessful()&&response.code()==200){ final String result = response.body().string(); handler.post(new Runnable() { @Override public void run() { callback.success(result); } }); } } } }); } public interface ICallback{ void success(String result); void fail (String msg); } }AppUtils
public class AppUtils { public static int screenWidth(Context context){ DisplayMetrics metrics=context.getResources().getDisplayMetrics(); return metrics.widthPixels; } }
//NetWorkUtil
public class NetWorkUtil { /** * * @return 是否有活动的网络连接 */ public final static boolean hasNetWorkConnection(Context context){ //获取连接活动管理器 final ConnectivityManager connectivityManager= (ConnectivityManager) context. getSystemService(Context.CONNECTIVITY_SERVICE); //获取链接网络信息 final NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo(); return (networkInfo!= null && networkInfo.isAvailable()); } /** * @return 返回boolean ,是否为wifi网络 * */ public final static boolean hasWifiConnection(Context context) { final ConnectivityManager connectivityManager= (ConnectivityManager) context. getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo networkInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); //是否有网络并且已经连接 return (networkInfo!=null&& networkInfo.isConnectedOrConnecting()); } /** * @return 返回boolean,判断网络是否可用,是否为移动网络 * */ public final static boolean hasGPRSConnection(Context context){ //获取活动连接管理器 final ConnectivityManager connectivityManager= (ConnectivityManager) context. getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo networkInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); return (networkInfo!=null && networkInfo.isAvailable()); } /** * @return 判断网络是否可用,并返回网络类型,ConnectivityManager.TYPE_WIFI,ConnectivityManager.TYPE_MOBILE,不可用返回-1 */ public static final int getNetWorkConnectionType(Context context){ final ConnectivityManager connectivityManager=(ConnectivityManager) context. getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo wifiNetworkInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); final NetworkInfo mobileNetworkInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); if(wifiNetworkInfo!=null &&wifiNetworkInfo.isAvailable()) { return ConnectivityManager.TYPE_WIFI; } else if(mobileNetworkInfo!=null &&mobileNetworkInfo.isAvailable()) { return ConnectivityManager.TYPE_MOBILE; } else { return -1; } } }
//Constants
public class Constants { public static final String GET_URL="http://ttpc.dftoutiao.com/jsonpc/refresh"; public static final int TYPE1=3; public static final int TYPE2=1; }
//MainActivity
public class MainActivity extends AppCompatActivity implements IView { private XRecyclerView rv; private BeanPresenter presenter; private int page=5010; private List<Bean.DataBean> data; private boolean isRefresh=true; private Myadapter myadapter; private DbHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } private void initData() { if (getIntent().getExtras()!=null){ page=5010+Integer.parseInt(getIntent().getExtras().getString("id")); } dbHelper =new DbHelper(this); presenter = new BeanPresenter(this); // Map<String,String> params=new HashMap<>(); // params.put("type",page+""); // presenter.getData(Constants.GET_URL,params); data=new ArrayList<>(); request(); } private void request() { if (NetWorkUtil.hasWifiConnection(this)||NetWorkUtil.hasGPRSConnection(this)){ Map<String,String> p=new HashMap<>(); p.put("type",page+""); presenter.getData(Constants.GET_URL,p); }else { Toast.makeText(this, "网络不通畅,请稍后再试!", Toast.LENGTH_SHORT).show(); String json=null; SQLiteDatabase db=dbHelper.getReadableDatabase(); Cursor cursor=db.rawQuery("select * from news",null); while (cursor.moveToNext()){ json=cursor.getString(cursor.getColumnIndex("json")); } fillLocalData(json); } } private void fillLocalData(String json) { Bean bean=new Gson().fromJson(json,Bean.class); myadapter=new Myadapter(bean.getData(),this); rv.setAdapter(myadapter); } private void initView() { rv = findViewById(R.id.rv); rv.setLayoutManager(new LinearLayoutManager(this));//布局管理器 rv.setItemAnimator(new DefaultItemAnimator()); rv.setPullRefreshEnabled(true); rv.setLoadingMoreEnabled(true); rv.setLoadingListener(new XRecyclerView.LoadingListener() { @Override public void onRefresh() { isRefresh=true; page=5010; request(); // initData(); // rv.refreshComplete(); } @Override public void onLoadMore() { isRefresh=false; page++; request(); // rv.loadMoreComplete(); } }); } //这还没有改 @Override public void success(Bean bean) { // rv.setLayoutManager(new LinearLayoutManager(this)); // Myadapter myadapter=new Myadapter(bean.getData(),this); // rv.setAdapter(myadapter); String json=new Gson().toJson(bean); data=bean.getData(); if (isRefresh){ myadapter=new Myadapter(data,this); rv.setAdapter(myadapter); rv.refreshComplete(); SQLiteDatabase db=dbHelper.getWritableDatabase(); ContentValues contentValues=new ContentValues(); contentValues.put("json",json); db.insert(DbHelper.NEWS_TABLE_NAME,null,contentValues); }else { if (myadapter!=null){ myadapter.loadMore(bean.getData()); } rv.loadMoreComplete(); } } protected void onDestroy() { super.onDestroy(); presenter.detach(); } }
//activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.jcodecraeer.xrecyclerview.XRecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="wrap_content"></com.jcodecraeer.xrecyclerview.XRecyclerView> </LinearLayout>
/adapter包
MyAdapter
public class Myadapter extends XRecyclerView.Adapter<RecyclerView.ViewHolder> { private List<Bean.DataBean> list; private Context context; private Bean bean; public Myadapter(List<Bean.DataBean> list, Context context) { this.list = list; this.context = context; this.bean=bean; } public void loadMore(List<Bean.DataBean> data){ if (list!=null){ list.addAll(data); notifyDataSetChanged(); } } @Override public XRecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType== Constants.TYPE1){ View view= LayoutInflater.from(context).inflate(R.layout.item2_layout,parent,false); return new TypeViewHolder(view); }else{ View view2= LayoutInflater.from(context).inflate(R.layout.item1_layout,parent,false); return new Type2ViewHolder(view2); } } @Override public void onBindViewHolder(final XRecyclerView.ViewHolder holder, int position) { holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { AlertDialog.Builder builder=new AlertDialog.Builder(context); builder.setTitle("删除"); builder.setNegativeButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { int pos=holder.getLayoutPosition()-1; list.remove(pos); //list=bean.getData(); //String json=new Gson().toJson(bean); notifyItemRemoved(pos); } }); builder.setNeutralButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); builder.show(); return true; } }); Bean.DataBean data = list.get(position); if (holder instanceof TypeViewHolder) {//1张图片 ((TypeViewHolder) holder).tw.setText(data.getBrief()); } else if (holder instanceof Type2ViewHolder) {//三张图片 ((Type2ViewHolder) holder).tw.setText(data.getTopic()); if (data.getMiniimg()!=null&&data.getMiniimg().size()>0){ if (data.getMiniimg().size()==1){ Glide.with(context).load(data.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iw2); Glide.with(context).load(data.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iw3); Glide.with(context).load(data.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iw4); }else if (data.getMiniimg().size()==2){ Glide.with(context).load(data.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iw2); Glide.with(context).load(data.getMiniimg().get(1).getSrc()).into(((Type2ViewHolder) holder).iw3); Glide.with(context).load(data.getMiniimg().get(1).getSrc()).into(((Type2ViewHolder) holder).iw4); }else{ Glide.with(context).load(data.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iw2); Glide.with(context).load(data.getMiniimg().get(1).getSrc()).into(((Type2ViewHolder) holder).iw3); Glide.with(context).load(data.getMiniimg().get(2).getSrc()).into(((Type2ViewHolder) holder).iw4); } } } } public int getItemViewType(int position){ return position%2==0 ? Constants.TYPE1:Constants.TYPE2; } @Override public int getItemCount() { return list.size(); } class TypeViewHolder extends XRecyclerView.ViewHolder{ private final TextView tw; public TypeViewHolder(View itemView) { super(itemView); tw = itemView.findViewById(R.id.tw1); } } class Type2ViewHolder extends XRecyclerView.ViewHolder{ private final ImageView iw2; private final ImageView iw3; private final ImageView iw4; private final TextView tw; public Type2ViewHolder(View itemView) { super(itemView); iw2 = itemView.findViewById(R.id.iw2); iw3 = itemView.findViewById(R.id.iw3); iw4 = itemView.findViewById(R.id.iw4); tw = itemView.findViewById(R.id.tw2); } } }
db包
//DbHelper
public class DbHelper extends SQLiteOpenHelper { private static final String DB_NAME = "news.db"; public static final String NEWS_TABLE_NAME = "news"; private static final int VERSION = 1; public DbHelper(Context context) { super(context, DB_NAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { String sql="create table " + NEWS_TABLE_NAME + " (_id Integer PRIMARY KEY ,json text)"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
/widget包
/ThreeView
public class ThreeView extends ViewGroup { public ThreeView(Context context) { super(context); } public ThreeView(Context context, AttributeSet attrs) { super(context, attrs); } public ThreeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){ super.onMeasure(widthMeasureSpec, heightMeasureSpec); int totalHeight=0; int totalWidth=0; int child=getChildCount(); if (child>0){ for (int i=0;i<child;i++){ View view=getChildAt(i); totalHeight +=view.getMeasuredHeight(); measureChild(view,widthMeasureSpec,heightMeasureSpec); } } totalWidth= AppUtils.screenWidth(getContext()); setMeasuredDimension(totalWidth,totalHeight); } @Override protected void onLayout(boolean bo, int left, int top, int right, int bottom) { int l =0; int t=0; int r=0; int b=0; int childCount=getChildCount(); for (int i=0;i<childCount;i++){ final View view=getChildAt(i); view.layout(l,t,l+view.getMeasuredWidth(),t+view.getMeasuredHeight()); l+=view.getMeasuredWidth(); t+=view.getMeasuredHeight(); if (l+view.getMeasuredWidth()>AppUtils.screenWidth(getContext())){ l=0; } final int finalI =i; view.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { Toast.makeText(getContext(), finalI +":点击位置", Toast.LENGTH_SHORT).show(); TextView textView=(TextView) view; Toast.makeText(getContext(), textView.getText().toString() +"文本", Toast.LENGTH_SHORT).show(); Intent intent=new Intent(getContext(), MainActivity.class); intent.putExtra("id",textView.getText().toString()); getContext().startActivity(intent); } }); view.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { Toast.makeText(getContext(), finalI +":长按位置", Toast.LENGTH_SHORT).show(); removeView(v); return true; } }); } } }
//ThreeActivity
public class ThreeActivity extends AppCompatActivity { private ThreeView threeView; private int count=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_three); threeView=findViewById(R.id.threeview); } public void add(View view){ count++; int width= AppUtils.screenWidth(this); TextView textView=new TextView(this); textView.setText(count+""); textView.setGravity(Gravity.CENTER); textView.setTextColor(getResources().getColor(R.color.white)); ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(textView,"translationX",(width-width/3),0); objectAnimator.setDuration(1000); objectAnimator.start(); if (count==1||count==4||count==7){ textView.setBackgroundColor(getResources().getColor(R.color.colorAccent)); }else{ textView.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark)); } threeView.addView(textView); ViewGroup.LayoutParams params=textView.getLayoutParams(); params.width=width/3; params.height=70; textView.setLayoutParams(params); } }
/bean包
/LocalBean
public class LocalBean { public String title; public String imgurls; public String source; public String time; public boolean isDel; }
///item1_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:orientation="vertical"> <TextView android:id="@+id/tw2" android:text="我是标题" android:layout_width="match_parent" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginTop="10dp"> <ImageView android:id="@+id/iw2" android:layout_width="0dp" android:layout_weight="1" android:scaleType="centerCrop" android:src="@mipmap/ic_launcher" android:layout_height="70dp" /> <ImageView android:id="@+id/iw3" android:layout_width="0dp" android:layout_weight="1" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:scaleType="centerCrop" android:src="@mipmap/ic_launcher" android:layout_height="70dp" /> <ImageView android:id="@+id/iw4" android:layout_width="0dp" android:layout_weight="1" android:src="@mipmap/ic_launcher" android:layout_height="70dp" /> </LinearLayout> </LinearLayout>
/item2_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp"> <ImageView android:id="@+id/iw1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerCrop"/> <LinearLayout android:layout_width="0dp" android:layout_weight="1" android:layout_marginTop="10dp" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是标题" android:layout_marginLeft="10dp" android:id="@+id/tw1"/> </LinearLayout> </LinearLayout>three_main
<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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.dell.myapplication.ThreeActivity"> <Button android:id="@+id/add" android:onClick="add" android:text="+" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.example.dell.myapplication.widget.ThreeView android:id="@+id/threeview" android:layout_width="match_parent" android:layout_height="wrap_content"></com.example.dell.myapplication.widget.ThreeView> </LinearLayout>
//依赖
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) //noinspection GradleCompatible implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'com.github.bumptech.glide:glide:4.7.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1' implementation 'com.jcodecraeer:xrecyclerview:1.5.9' implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0' implementation 'com.squareup.okhttp3:okhttp:3.10.0' implementation 'com.google.code.gson:gson:2.8.5' } configurations.all { resolutionStrategy.eachDependency { DependencyResolveDetails details -> def requested = details.requested if (requested.group == 'com.android.support') { if (!requested.name.startsWith("multidex")) { details.useVersion '27.1.1' } } }