登陆主界面
package com.example.zk2_mn;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements Vi{
private EditText phone;
private EditText pwd;
private Button dl;
private Button zc;
private Map<String, String> map;
private Pc pc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
phone = findViewById(R.id.phone);
pwd = findViewById(R.id.mm);
dl = findViewById(R.id.dl);
zc = findViewById(R.id.zc);
pc = new Pc(this);
zc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
}
});
dl.setOnClickListener(new View.OnClickListener() {
private String s1;
private String s;
@Override
public void onClick(View view) {
s = phone.getText().toString();
s1 = pwd.getText().toString();
map= new HashMap<>();
map.put("mobile",s);
map.put("password",s1);
pc.dl(map,MainActivity.this);
Intent intent=new Intent(MainActivity.this,Main3Activity.class);
startActivity(intent);
}
});
}
@Override
public void dl_OnSuccess(final dl_Bean dlBean) {
runOnUiThread(new Runnable() {
@Override
public void run() {
String msg = dlBean.getMsg();
if("登录成功".equals(msg)) {
Toast.makeText(MainActivity.this, "登陆成功", Toast.LENGTH_SHORT).show();
Log.d("zzz", dlBean.getData().toString());
}
}
});
}
@Override
public void dl_Onfailed() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "登陆失败", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void zc_OnSuccess(zc_Bean zcBean) {
}
@Override
public void zc_OnFailed() {
}
@Override
public void OnSuccess(Bean bean) {
}
@Override
public void OnFailed() {
}
//mvp解绑
@Override
protected void onDestroy() {
super.onDestroy();
if(pc!=null){
pc.onDestory();
}
}
}
注册主界面
package com.example.zk2_mn;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class Main2Activity extends AppCompatActivity implements Vi{
private EditText phone;
private Button zc_zc;
private EditText mm;
private Pc pc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
phone = findViewById(R.id.zc_phone);
zc_zc = findViewById(R.id.zc_zc);
mm = findViewById(R.id.z_mm);
pc = new Pc(this);
zc_zc.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String s = phone.getText().toString();
String s1 = mm.getText().toString();
pc.zc(s,s1,Main2Activity.this);
Log.d("zzz", "onClick: "+s.toString());
Log.d("zzz", "onClick: "+s1.toString());
}
});
}
@Override
public void dl_OnSuccess(dl_Bean dlBean) {
}
@Override
public void dl_Onfailed() {
}
@Override
public void zc_OnSuccess(final zc_Bean zcBean) {
runOnUiThread(new Runnable() {
@Override
public void run() {
String msg = zcBean.getMsg();
if ("注册成功".equals(msg)){
Toast.makeText(Main2Activity.this, "注册成功", Toast.LENGTH_SHORT).show();
Intent intent=new Intent(Main2Activity.this,MainActivity.class);
startActivity(intent);
finish();
}
}
});
}
@Override
public void zc_OnFailed() {
}
@Override
public void OnSuccess(Bean bean) {
}
@Override
public void OnFailed() {
}
}
流式布局主界面
package com.example.zk2_mn;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class Main3Activity extends AppCompatActivity {
private String mNames[] = {
"洗衣机","IT","第二",
"电冰箱","水果","第二第一",
"电脑","苹果","viewgroup",
"电磁炉","第二","第二"};
private ReSou reSouView;
private EditText name;
private Dao dao;
private ListView lv;
private ArrayAdapter<String> adapter;
private List<String> sel;
private Button btn;
List<String> a=new ArrayList<>();
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
reSouView = findViewById(R.id.reSouView);
//找控件
name = findViewById(R.id.et_sou);
//热搜
initChildViews();
lv = (ListView) findViewById(R.id.lv);
btn = (Button) findViewById(R.id.btn);
dao = new Dao(Main3Activity.this);
sel = dao.sel();
adapter = new ArrayAdapter<>(Main3Activity.this, android.R.layout.simple_list_item_1, android.R.id.text1, sel);
lv.setAdapter(adapter);
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int d, long l) {
AlertDialog.Builder ab=new AlertDialog.Builder(Main3Activity.this);
ab.setTitle("是否删除");
Log.d("aaa",sel.get(d).toString());
ab.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
int delyi = dao.delyi(sel.get(d).toString());
if (delyi==1){
zhanshi();
}
}
});
ab.setNegativeButton("取消",null);
ab.show();
return false;
}
});
if (sel.size()>0){
btn.setVisibility(View.VISIBLE);
}else if(sel.size()==0)
{
btn.setVisibility(View.INVISIBLE);
}
}
private void zhanshi() {
List<String> sel4 = dao.sel();
ArrayAdapter<String> ada = new ArrayAdapter<>(Main3Activity.this, android.R.layout.simple_list_item_1, android.R.id.text1, sel4);
lv.setAdapter(ada);
}
private void initChildViews() {
// TODO Auto-generated method stub
reSouView = findViewById(R.id.reSouView);
ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.leftMargin = 5;
lp.rightMargin = 5;
lp.topMargin = 5;
lp.bottomMargin = 5;
for(int i = 0; i < mNames.length; i ++){
TextView view = new TextView(this);
view.setText(mNames[i]);
view.setTextColor(Color.WHITE);
view.setBackgroundDrawable(getResources().getDrawable(R.drawable.textshape));
reSouView.addView(view,lp);
}
}
public void add(View view) {
String n = name.getText().toString();
int i = dao.insertJson(n);
btn.setVisibility(View.VISIBLE);
List<String> sel3 = dao.sel();
a.add(0,n);
ArrayAdapter<String> adapter3 = new ArrayAdapter<>(Main3Activity.this, android.R.layout.simple_list_item_1, android.R.id.text1, a);
lv.setAdapter(adapter3);
Intent intent=new Intent(Main3Activity.this,Main4Activity.class);
startActivity(intent);
}
public void delall(View view) {
dao.del();
List<String> sel2 = dao.sel();
ArrayAdapter<String> adapter2 = new ArrayAdapter<>(Main3Activity.this, android.R.layout.simple_list_item_1, android.R.id.text1, sel2);
lv.setAdapter(adapter2);
Toast.makeText(Main3Activity.this,"清除成功",Toast.LENGTH_LONG).show();
btn.setVisibility(View.INVISIBLE);
}
}
搜索切换布局主界面
package com.example.zk2_mn;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.jcodecraeer.xrecyclerview.XRecyclerView;
import java.util.List;
public class Main4Activity extends AppCompatActivity implements Vi{
private EditText et;
private Button ss;
private Button qh;
private XRecyclerView re;
Boolean flag=true;
private MyAdapter adapter;
private LinearLayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
et = findViewById(R.id.et);
ss = findViewById(R.id.ss);
qh = findViewById(R.id.qh);
re = findViewById(R.id.re);
re.setLoadingListener(new XRecyclerView.LoadingListener() {
@Override
public void onRefresh() {
adapter.notifyDataSetChanged();
}
@Override
public void onLoadMore() {
adapter.notifyDataSetChanged();
}
});
ss.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String s = et.getText().toString();
Pc pc=new Pc(Main4Activity.this);
pc.info(s);
}
});
qh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(flag){
layoutManager = new LinearLayoutManager(Main4Activity.this, LinearLayoutManager.VERTICAL, false);
re.setLayoutManager(layoutManager);
//re.setAdapter(adapter);
flag=false;
}else {
GridLayoutManager gridLayoutManager=new GridLayoutManager(Main4Activity.this,2,GridLayoutManager.VERTICAL,false);
re.setLayoutManager(gridLayoutManager);
//re.setAdapter(adapter);
flag=true;
}
}
});
}
@Override
public void dl_OnSuccess(dl_Bean dlBean) {
}
@Override
public void dl_Onfailed() {
}
@Override
public void zc_OnSuccess(zc_Bean zcBean) {
}
@Override
public void zc_OnFailed() {
}
@Override
public void OnSuccess(final Bean bean) {
runOnUiThread(new Runnable() {
@Override
public void run() {
List<Bean.DataBean> data = bean.getData();
adapter = new MyAdapter(Main4Activity.this,data);
layoutManager = new LinearLayoutManager(Main4Activity.this, LinearLayoutManager.VERTICAL, false);
re.setLayoutManager(layoutManager);
re.setAdapter(adapter);
}
});
}
@Override
public void OnFailed() {
}
}
M层
package com.example.zk2_mn;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
/**
* author:Created by MingShao on 2018/1/6.
*/
public class Mc {
public void dl(Map<String,String> map, final Pi pi){
OkHttp3Util.doPost(Wz.dl, map, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()){
String string = response.body().string();
dl_Bean dl_bean = new Gson().fromJson(string, dl_Bean.class);
pi.dl_OnSuccess(dl_bean);
}
}
});
}
public void zc(String name,String pwd, final Pi pi){
String regex = "^1[3|4|5|7|8]\\d{9}";
if(TextUtils.isEmpty(name)){
Log.d("wode", "dopost: "+"手机号不能为空");
return;
}else if(TextUtils.isEmpty(pwd)) {
Log.d("wode", "dopost: " + "密码不能为空");
return;
}else if(!Pattern.matches(regex,name)){
Log.d("wode", "dopost: "+"手机号格式不正确");
return ;
}else if(pwd.length()<6){
Log.d("wode", "dopost: "+"密码不能小于6位");
return ;
}
Map<String ,String> map = new HashMap<>();
map.put("mobile",name);
map.put("password",pwd);
OkHttp3Util.doPost(Wz.zc, map,new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()){
String string = response.body().string();
zc_Bean zcBean = new Gson().fromJson(string, zc_Bean.class);
Log.d("zzz",zcBean.toString());
pi.zc_OnSuccess(zcBean);
}
}
});
}
public void info(String keywords, final Pi pi){
Map<String,String> map=new HashMap<>();
map.put("keywords",keywords);
map.put("page",1+"");
OkHttp3Util.doPost("https://www.zhaoapi.cn/product/searchProducts?source=android", map, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
String string = response.body().string();
Bean bean = new Gson().fromJson(string, Bean.class);
pi.OnSuccess(bean);
Log.d("zzz", "onResponse: "+bean.toString());
}
}
});
}
}
P层
package com.example.zk2_mn;
import java.util.Map;
/**
* author:Created by MingShao on 2018/1/6.
*/
public class Pc implements Pi {
Vi vi;
Mc mc;
public Pc(Vi vi) {
this.vi = vi;
mc=new Mc();
}
public void dl(Map<String,String> map,Vi vi){
mc.dl(map,this);
}
public void zc(String phone,String pwd,Vi vi){
mc.zc(phone,pwd,this);
}
public void info(String keywords){
mc.info(keywords,this);
}
@Override
public void dl_OnSuccess(dl_Bean dlBean) {
vi.dl_OnSuccess(dlBean);
}
@Override
public void dl_Onfailed() {
}
@Override
public void zc_OnSuccess(zc_Bean zcBean) {
vi.zc_OnSuccess(zcBean);
}
@Override
public void zc_OnFailed() {
}
@Override
public void OnSuccess(Bean bean) {
vi.OnSuccess(bean);
}
@Override
public void OnFailed() {
}
//mvp解绑用
@Override
protected void onDestroy() {
super.onDestroy();
if(pc!=null){
pc.onDestory();
}
}
}
P层接口
package com.example.zk2_mn;
/**
* author:Created by MingShao on 2018/1/6.
*/
public interface Pi {
void dl_OnSuccess(dl_Bean dlBean);
void dl_Onfailed();
void zc_OnSuccess(zc_Bean zcBean);
void zc_OnFailed();
void OnSuccess(Bean bean);
void OnFailed();
}
V层接口
package com.example.zk2_mn;
/**
* author:Created by MingShao on 2018/1/6.
*/
public interface Vi {
void dl_OnSuccess(dl_Bean dlBean);
void dl_Onfailed();
void zc_OnSuccess(zc_Bean zcBean);
void zc_OnFailed();
void OnSuccess(Bean bean);
void OnFailed();
}
登陆注册所用网址
package com.example.zk2_mn;
/**
* author:Created by MingShao on 2018/1/6.
*/
public interface Wz {
final String dl="https://www.zhaoapi.cn/user/login";
final String zc="https://www.zhaoapi.cn/user/reg";
}
流式布局数据库
package com.example.zk2_mn;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import java.util.List;
/**
* author:Created by MingShao on 2018/1/6.
*/
public class Dao {
private Myhelpher my;
private SQLiteDatabase db;
private SQLiteDatabase d;
public Dao(Context context) {
my= new Myhelpher(context);
}
/**
* 插入数据的操作
*/
public int insertJson(String json){
SQLiteDatabase database = my.getWritableDatabase();
//再去添加
ContentValues values = new ContentValues();
values.put("json",json);
database.insert("shuju1",null,values);
//关闭
database.close();
return 1;
}
public List<String> sel(){
d = my.getReadableDatabase();
List<String> list=new ArrayList<>();
Cursor cursor = d.rawQuery("select * from shuju1", null);
while (cursor.moveToNext()){
String s = cursor.getString(1);
list.add(s);
}
return list;
}
public void del(){
db = my.getWritableDatabase();
db.execSQL("delete from shuju1");
}
public int delyi(String i){
db = my.getWritableDatabase();
db.execSQL("delete from shuju1 where json=?",new String[]{i});
return 1;
}
}
package com.example.zk2_mn;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* author:Created by MingShao on 2018/1/6.
*/
public class Myhelpher extends SQLiteOpenHelper {
public Myhelpher(Context context) {
super(context,"sss.db",null, 2);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
//创建表
sqLiteDatabase.execSQL("create table shuju1(id integer primary key autoincrement,json text not null)");
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
热搜的自定义类
package com.example.zk2_mn;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* author:Created by MingShao on 2018/1/6.
*/
public class ReSou extends ViewGroup{
//存储所有子View
private List<List<View>> mAllChildViews = new ArrayList<>();
//每一行的高度
private List<Integer> mLineHeight = new ArrayList<>();
public ReSou(Context context) {
super(context);
}
public ReSou(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ReSou(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mAllChildViews.clear();
mLineHeight.clear();
//获取当前ViewGroup的宽度
int width = getWidth();
int lineWidth = 0;
int lineHeight = 0;
//记录当前行的view
List<View> lineViews = new ArrayList<View>();
int childCount = getChildCount();
for(int i = 0;i < childCount; i ++){
View child = getChildAt(i);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
//如果需要换行
if(childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width){
//记录LineHeight
mLineHeight.add(lineHeight);
//记录当前行的Views
mAllChildViews.add(lineViews);
//重置行的宽高
lineWidth = 0;
lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
//重置view的集合
lineViews = new ArrayList();
}
lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
lineViews.add(child);
}
//处理最后一行
mLineHeight.add(lineHeight);
mAllChildViews.add(lineViews);
//设置子View的位置
int left = 0;
int top = 0;
//获取行数
int lineCount = mAllChildViews.size();
for(int i = 0; i < lineCount; i ++){
//当前行的views和高度
lineViews = mAllChildViews.get(i);
lineHeight = mLineHeight.get(i);
for(int j = 0; j < lineViews.size(); j ++){
View child = lineViews.get(j);
//判断是否显示
if(child.getVisibility() == View.GONE){
continue;
}
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int cLeft = left + lp.leftMargin;
int cTop = top + lp.topMargin;
int cRight = cLeft + child.getMeasuredWidth();
int cBottom = cTop + child.getMeasuredHeight();
//进行子View进行布局
child.layout(cLeft, cTop, cRight, cBottom);
left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
left = 0;
top += lineHeight;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//父控件传进来的宽度和高度以及对应的测量模式
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
//如果当前ViewGroup的宽高为wrap_content的情况
int width = 0;//自己测量的 宽度
int height = 0;//自己测量的高度
//记录每一行的宽度和高度
int lineWidth = 0;
int lineHeight = 0;
//获取子view的个数
int childCount = getChildCount();
for(int i = 0;i < childCount; i ++){
View child = getChildAt(i);
//测量子View的宽和高
measureChild(child, widthMeasureSpec, heightMeasureSpec);
//得到LayoutParams
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
//子View占据的宽度
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
//子View占据的高度
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
//换行时候
if(lineWidth + childWidth > sizeWidth){
//对比得到最大的宽度
width = Math.max(width, lineWidth);
//重置lineWidth
lineWidth = childWidth;
//记录行高
height += lineHeight;
lineHeight = childHeight;
}else{//不换行情况
//叠加行宽
lineWidth += childWidth;
//得到最大行高
lineHeight = Math.max(lineHeight, childHeight);
}
//处理最后一个子View的情况
if(i == childCount -1){
width = Math.max(width, lineWidth);
height += lineHeight;
}
}
//wrap_content
setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width,
modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height);
}
/**
* 与当前ViewGroup对应的LayoutParams
*/
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
// TODO Auto-generated method stub
return new MarginLayoutParams(getContext(), attrs);
}
}
搜索的适配器
package com.example.zk2_mn;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.List;
/**
* author:Created by MingShao on 2018/1/5.
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
Context context;
List<Bean.DataBean> data;
private ViewHolder holder;
public MyAdapter(Context context, List<Bean.DataBean> data) {
this.context = context;
this.data = data;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LinearLayout.inflate(context, R.layout.item, null);
holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.tv.setText(data.get(position).getTitle());
String[] split = data.get(position).getImages().split("\\|");
Glide.with(context).load(split[0]).into(holder.img);
}
@Override
public int getItemCount() {
return data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView img;
TextView tv;
public ViewHolder(View itemView) {
super(itemView);
img= itemView.findViewById(R.id.img);
tv=itemView.findViewById(R.id.tv);
}
}
}
ok
package com.example.zk2_mn;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* author:Created by MingShao on 2018/1/6.
*/
public class OkHttp3Util {
private static OkHttpClient okHttpClient = null;
private OkHttp3Util() {
}
public static OkHttpClient getInstance() {
if (okHttpClient == null) {
//加同步安全
synchronized (OkHttp3Util.class) {
if (okHttpClient == null) {
//okhttp可以缓存数据....指定缓存路径
File sdcache = new File(Environment.getExternalStorageDirectory(), "cache");
//指定缓存大小
int cacheSize = 10 * 1024 * 1024;
okHttpClient = new OkHttpClient.Builder()//构建器
.connectTimeout(15, TimeUnit.SECONDS)//连接超时
.writeTimeout(20, TimeUnit.SECONDS)//写入超时
.readTimeout(20, TimeUnit.SECONDS)//读取超时
//.addInterceptor(new CommonParamsInterceptor())//添加的是应用拦截器...公共参数
//.addNetworkInterceptor(new CacheInterceptor())//添加的网络拦截器
.cache(new Cache(sdcache.getAbsoluteFile(), cacheSize))//设置缓存
.build();
}
}
}
return okHttpClient;
}
/**
* get请求
* 参数1 url
* 参数2 回调Callback
*/
public static void doGet(String oldUrl, Callback callback) {
//要添加的公共参数...map
Map<String,String> map = new HashMap<>();
map.put("source","android");
StringBuilder stringBuilder = new StringBuilder();//创建一个stringBuilder
stringBuilder.append(oldUrl);
if (oldUrl.contains("?")){
//?在最后面....2类型
if (oldUrl.indexOf("?") == oldUrl.length()-1){
}else {
//3类型...拼接上&
stringBuilder.append("&");
}
}else {
//不包含? 属于1类型,,,先拼接上?号
stringBuilder.append("?");
}
//添加公共参数....
for (Map.Entry<String,String> entry: map.entrySet()) {
//拼接
stringBuilder.append(entry.getKey())
.append("=")
.append(entry.getValue())
.append("&");
}
//删掉最后一个&符号
if (stringBuilder.indexOf("&") != -1){
stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("&"));
}
String newUrl = stringBuilder.toString();//新的路径
//创建OkHttpClient请求对象
OkHttpClient okHttpClient = getInstance();
//创建Request
Request request = new Request.Builder().url(newUrl).build();
//得到Call对象
Call call = okHttpClient.newCall(request);
//执行异步请求
call.enqueue(callback);
}
/**
* post请求
* 参数1 url
* 参数2 Map<String, String> params post请求的时候给服务器传的数据
* add..("","")
* add()
*/
public static void doPost(String url, Map<String, String> params, Callback callback) {
//要添加的公共参数...map
Map<String,String> map = new HashMap<>();
map.put("source","android");
//创建OkHttpClient请求对象
OkHttpClient okHttpClient = getInstance();
//3.x版本post请求换成FormBody 封装键值对参数
FormBody.Builder builder = new FormBody.Builder();
//遍历集合
for (String key : params.keySet()) {
builder.add(key, params.get(key));
}
//添加公共参数
for (Map.Entry<String,String> entry: map.entrySet()) {
builder.add(entry.getKey(),entry.getValue());
}
//创建Request
Request request = new Request.Builder().url(url).post(builder.build()).build();
Call call = okHttpClient.newCall(request);
call.enqueue(callback);
}
/**
* post请求上传文件....包括图片....流的形式传任意文件...
* 参数1 url
* file表示上传的文件
* fileName....文件的名字,,例如aaa.jpg
* params ....传递除了file文件 其他的参数放到map集合
*
*/
public static void uploadFile(String url, File file, String fileName,Map<String,String> params) {
//创建OkHttpClient请求对象
OkHttpClient okHttpClient = getInstance();
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
//参数
if (params != null){
for (String key : params.keySet()){
builder.addFormDataPart(key,params.get(key));
}
}
//文件...参数name指的是请求路径中所接受的参数...如果路径接收参数键值是fileeeee,此处应该改变
builder.addFormDataPart("file",fileName, RequestBody.create(MediaType.parse("application/octet-stream"),file));
//构建
MultipartBody multipartBody = builder.build();
//创建Request
Request request = new Request.Builder().url(url).post(multipartBody).build();
//得到Call
Call call = okHttpClient.newCall(request);
//执行请求
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("upload",e.getLocalizedMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//上传成功回调 目前不需要处理
if (response.isSuccessful()){
String s = response.body().string();
Log.e("upload","上传--"+s);
}
}
});
}
/**
* Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"}
* 参数一:请求Url
* 参数二:请求的JSON
* 参数三:请求回调
*/
public static void doPostJson(String url, String jsonParams, Callback callback) {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
Request request = new Request.Builder().url(url).post(requestBody).build();
Call call = getInstance().newCall(request);
call.enqueue(callback);
}
/**
* 下载文件 以流的形式把apk写入的指定文件 得到file后进行安装
* 参数er:请求Url
* 参数san:保存文件的文件夹....download
*/
public static void download(final Activity context, final String url, final String saveDir) {
Request request = new Request.Builder().url(url).build();
Call call = getInstance().newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//com.orhanobut.logger.Logger.e(e.getLocalizedMessage());
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
try {
is = response.body().byteStream();//以字节流的形式拿回响应实体内容
//apk保存路径
final String fileDir = isExistDir(saveDir);
//文件
File file = new File(fileDir, getNameFromUrl(url));
fos = new FileOutputStream(file);
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.flush();
context.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, "下载成功:" + fileDir + "," + getNameFromUrl(url), Toast.LENGTH_SHORT).show();
}
});
//apk下载完成后 调用系统的安装方法
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
context.startActivity(intent);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) is.close();
if (fos != null) fos.close();
}
}
});
}
/**
* 判断下载目录是否存在......并返回绝对路径
*
* @param saveDir
* @return
* @throws IOException
*/
public static String isExistDir(String saveDir) throws IOException {
// 下载位置
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
if (!downloadFile.mkdirs()) {
downloadFile.createNewFile();
}
String savePath = downloadFile.getAbsolutePath();
Log.e("savePath", savePath);
return savePath;
}
return null;
}
/**
* @param url
* @return 从下载连接中解析出文件名
*/
private static String getNameFromUrl(String url) {
return url.substring(url.lastIndexOf("/") + 1);
}
/**
* 公共参数拦截器
*/
private static class CommonParamsInterceptor implements Interceptor {
//拦截的方法
@Override
public Response intercept(Chain chain) throws IOException {
//获取到请求
Request request = chain.request();
//获取请求的方式
String method = request.method();
//获取请求的路径
String oldUrl = request.url().toString();
Log.e("---拦截器",request.url()+"---"+request.method()+"--"+request.header("User-agent"));
//要添加的公共参数...map
Map<String,String> map = new HashMap<>();
map.put("source","android");
if ("GET".equals(method)){
// 1.http://www.baoidu.com/login --------? key=value&key=value
// 2.http://www.baoidu.com/login? --------- key=value&key=value
// 3.http://www.baoidu.com/login?mobile=11111 -----&key=value&key=value
StringBuilder stringBuilder = new StringBuilder();//创建一个stringBuilder
stringBuilder.append(oldUrl);
if (oldUrl.contains("?")){
//?在最后面....2类型
if (oldUrl.indexOf("?") == oldUrl.length()-1){
}else {
//3类型...拼接上&
stringBuilder.append("&");
}
}else {
//不包含? 属于1类型,,,先拼接上?号
stringBuilder.append("?");
}
//添加公共参数....
for (Map.Entry<String,String> entry: map.entrySet()) {
//拼接
stringBuilder.append(entry.getKey())
.append("=")
.append(entry.getValue())
.append("&");
}
//删掉最后一个&符号
if (stringBuilder.indexOf("&") != -1){
stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("&"));
}
String newUrl = stringBuilder.toString();//新的路径
//拿着新的路径重新构建请求
request = request.newBuilder()
.url(newUrl)
.build();
}else if ("POST".equals(method)){
//先获取到老的请求的实体内容
RequestBody oldRequestBody = request.body();//....之前的请求参数,,,需要放到新的请求实体内容中去
//如果请求调用的是上面doPost方法
if (oldRequestBody instanceof FormBody){
FormBody oldBody = (FormBody) oldRequestBody;
//构建一个新的请求实体内容
FormBody.Builder builder = new FormBody.Builder();
//1.添加老的参数
for (int i=0;i<oldBody.size();i++){
builder.add(oldBody.name(i),oldBody.value(i));
}
//2.添加公共参数
for (Map.Entry<String,String> entry:map.entrySet()) {
builder.add(entry.getKey(),entry.getValue());
}
FormBody newBody = builder.build();//新的请求实体内容
//构建一个新的请求
request = request.newBuilder()
.url(oldUrl)
.post(newBody)
.build();
}
}
Response response = chain.proceed(request);
return response;
}
}
/**
* 网络缓存的拦截器......注意在这里更改cache-control头是很危险的,一般客户端不进行更改,,,,服务器端直接指定
*
* 没网络取缓存的时候,一般都是在数据库或者sharedPerfernce中取出来的
*
*
*
*/
/*private static class CacheInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
//老的响应
Response oldResponse = chain.proceed(chain.request());
*//*if (NetUtils.isNetworkConnected(DashApplication.getAppContext())){
int maxAge = 120; // 在线缓存在2分钟内可读取
return oldResponse.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
}else {
int maxStale = 60 * 60 * 24 * 14; // 离线时缓存保存2周
return oldResponse.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-Control")
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}*//*
}
}*/
}
热搜的布局
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.zk2_mn.Main3Activity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="@+id/btn_back"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:text=" 返回 "/>
<EditText
android:id="@+id/et_sou"
android:layout_width="0dp"
android:layout_weight="4"
android:hint="内衣跨店3免1,服装跨店3件7折"
android:layout_height="match_parent" />
<TextView
android:id="@+id/btn_sou"
android:onClick="add"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:text="搜索"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="热搜"
android:textSize="18sp"
android:textStyle="bold"/>
<com.example.zk2_mn.ReSou
android:id="@+id/reSouView"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="100dp"></com.example.zk2_mn.ReSou>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="历史记录"
android:textSize="24dp"
/>
<ListView
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="@+id/lv"
></ListView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清空历史记录"
android:layout_gravity="center"
android:gravity="center"
android:onClick="delall"
android:visibility="invisible"
android:id="@+id/btn"
/>
</LinearLayout>