300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 图片点击放大 松开缩小

图片点击放大 松开缩小

时间:2021-11-05 23:18:17

相关推荐

图片点击放大  松开缩小

权限

<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

依赖

//imageLoader

compile 'com.google.code.gson:gson:2.8.2'

//gson

compile 'com.squareup.okhttp3:okhttp:3.6.0'

//okhttp

compile 'com.squareup.okio:okio:1.11.0'

compile 'com.tencent.bugly:crashreport:latest.release'

//bugly

//其中latest.release指代最新版本号

compile 'com.orhanobut:logger:2.1.1'

//Logger

compile 'com.youth.banner:banner:1.4.10'

//最新版本...banner

implementation 'com.github.bumptech.glide:glide:4.4.0'

//glide

compile 'com.android.support:design:27.0.2'

//跑马灯

compile 'com.sunfusheng:marqueeview:1.3.3'

MainActivity类

package com.dash.xiangqingproject;

import android.content.Intent;

import android.support.v4.view.PagerAdapter;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

import com.bumptech.glide.Glide;

import com.google.gson.Gson;

import com.youth.banner.Banner;

import com.youth.banner.BannerConfig;

import com.youth.banner.listener.OnBannerListener;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import okhttp3.Call;

import okhttp3.Callback;

import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

private ViewPager viewPager;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

viewPager = findViewById(R.id.view_pager);

Map<String, String> params = new HashMap<>();

params.put("pid","47");

OkHttp3Util_03.doPost("/product/getProductDetail", params, new Callback() {

@Override

public void onFailure(Call call, IOException e) {

}

@Override

public void onResponse(Call call, Response response) throws IOException {

if (response.isSuccessful()){

String json = response.body().string();

final DetailBean detailBean = new Gson().fromJson(json,DetailBean.class);

if ("0".equals(detailBean.getCode())){

//展示轮播图...主线程

runOnUiThread(new Runnable() {

@Override

public void run() {

final ArrayList<String> imageUrls = new ArrayList<>();

String[] split = detailBean.getData().getImages().split("\\|");

for (int i =0;i<split.length;i++){

imageUrls.add(split[i]);

}

viewPager.setAdapter(new PagerAdapter() {

@Override

public Object instantiateItem(ViewGroup container, int position) {

ImageView imageView = new ImageView(MainActivity.this);

//加载图片显示

Glide.with(MainActivity.this).load(imageUrls.get(position)).into(imageView);

//添加

container.addView(imageView);

imageView.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

//跳转到下一个放大图片的页面,,,并传值过去

Intent intent = new Intent(MainActivity.this,PicActivity.class);

//直接传递string类型的arrayList

intent.putStringArrayListExtra("list",imageUrls);

startActivity(intent);

}

});

//返回

return imageView;

}

@Override

public void destroyItem(ViewGroup container, int position,

Object object) {

container.removeView((View) object);

}

@Override

public boolean isViewFromObject(View arg0, Object arg1) {

return arg0 == arg1;

}

@Override

public int getCount() {

return imageUrls.size();

}

});

}

});

}

}

}

});

}

}

PicActivity类

package com.dash.xiangqingproject;

import android.support.v4.view.PagerAdapter;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

import com.bumptech.glide.Glide;

import java.util.ArrayList;

public class PicActivity extends AppCompatActivity {

private ViewPager viewPager;

private ArrayList<String> imageUrls;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_pic);

viewPager = findViewById(R.id.view_pager);

//获取导数据

imageUrls = getIntent().getStringArrayListExtra("list");

if (imageUrls != null){

viewPager.setAdapter(new PagerAdapter() {

@Override

public Object instantiateItem(ViewGroup container, int position) {

ZoomImageView imageView = new ZoomImageView(PicActivity.this);

//加载图片显示

Glide.with(PicActivity.this).load(imageUrls.get(position)).into(imageView);

//添加

container.addView(imageView);

//返回

return imageView;

}

@Override

public void destroyItem(ViewGroup container, int position,

Object object) {

container.removeView((View) object);

}

@Override

public boolean isViewFromObject(View arg0, Object arg1) {

return arg0 == arg1;

}

@Override

public int getCount() {

return imageUrls.size();

}

});

}

}

}

ZoomImageView自定义类

package com.dash.xiangqingproject;

import android.annotation.SuppressLint;

import android.content.Context;

import android.graphics.Matrix;

import android.graphics.RectF;

import android.graphics.drawable.Drawable;

import android.support.v4.view.ViewPager;

import android.util.AttributeSet;

import android.util.Log;

import android.view.GestureDetector;

import android.view.MotionEvent;

import android.view.ScaleGestureDetector;

import android.view.ScaleGestureDetector.OnScaleGestureListener;

import android.view.View;

import android.view.View.OnTouchListener;

import android.view.ViewConfiguration;

import android.view.ViewTreeObserver;

import android.view.ViewTreeObserver.OnGlobalLayoutListener;

import android.widget.ImageView;

/**

* Created by Dash on /1/17.

*/

@SuppressLint("AppCompatCustomView")

public class ZoomImageView extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener, ScaleGestureDetector.OnScaleGestureListener, View.OnTouchListener {

private boolean mOnce;

/**

* 初始化时缩放的值

*/

private float mInitScale;

/**

* 双击放大值到达的值

*/

private float mMidScale;

/**

* 放大的最大值

*/

private float mMaxScale;

private Matrix mScaleMatrix;

/**

* 捕获用户多指触控时缩放的比例

*/

private ScaleGestureDetector mScaleGestureDetector;

// **********自由移动的变量***********

/**

* 记录上一次多点触控的数量

*/

private int mLastPointerCount;

private float mLastX;

private float mLastY;

private int mTouchSlop;

private boolean isCanDrag;

private boolean isCheckLeftAndRight;

private boolean isCheckTopAndBottom;

// *********双击放大与缩小*********

private GestureDetector mGestureDetector;

private boolean isAutoScale;

public ZoomImageView(Context context) {

this(context, null);

}

public ZoomImageView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public ZoomImageView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

// init

mScaleMatrix = new Matrix();

setScaleType(ScaleType.MATRIX);

setOnTouchListener(this);

mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

mScaleGestureDetector = new ScaleGestureDetector(context, this);

mGestureDetector = new GestureDetector(context,

new GestureDetector.SimpleOnGestureListener() {

@Override

public boolean onDoubleTap(MotionEvent e) {

if (isAutoScale) {

return true;

}

float x = e.getX();

float y = e.getY();

if (getScale() < mMidScale) {

postDelayed(new AutoScaleRunnable(mMidScale, x, y), 16);

isAutoScale = true;

} else {

postDelayed(new AutoScaleRunnable(mInitScale, x, y), 16);

isAutoScale = true;

}

return true;

}

});

}

/**

* 自动放大与缩小

*

* @author zhangyan@

*

*/

private class AutoScaleRunnable implements Runnable {

/**

* 缩放的目标值

*/

private float mTargetScale;

// 缩放的中心点

private float x;

private float y;

private final float BIGGER = 1.07f;

private final float SMALL = 0.93f;

private float tmpScale;

/**

* @param mTargetScale

* @param x

* @param y

*/

public AutoScaleRunnable(float mTargetScale, float x, float y) {

this.mTargetScale = mTargetScale;

this.x = x;

this.y = y;

if (getScale() < mTargetScale) {

tmpScale = BIGGER;

}

if (getScale() > mTargetScale) {

tmpScale = SMALL;

}

}

@Override

public void run() {

//进行缩放

mScaleMatrix.postScale(tmpScale, tmpScale, x, y);

checkBorderAndCenterWhenScale();

setImageMatrix(mScaleMatrix);

float currentScale = getScale();

if ((tmpScale >1.0f && currentScale <mTargetScale) ||(tmpScale<1.0f &&currentScale>mTargetScale)) {

//这个方法是重新调用run()方法

postDelayed(this, 16);

}else{

//设置为我们的目标值

float scale = mTargetScale/currentScale;

mScaleMatrix.postScale(scale, scale, x, y);

checkBorderAndCenterWhenScale();

setImageMatrix(mScaleMatrix);

isAutoScale = false;

}

}

}

/**

* 获取ImageView加载完成的图片

*/

@Override

public void onGlobalLayout() {

if (!mOnce) {

// 得到控件的宽和高

int width = getWidth();

int height = getHeight();

// 得到我们的图片,以及宽和高

Drawable drawable = getDrawable();

if (drawable == null) {

return;

}

int dh = drawable.getIntrinsicHeight();

int dw = drawable.getIntrinsicWidth();

float scale = 0.5f;

// 图片的宽度大于控件的宽度,图片的高度小于空间的高度,我们将其缩小

if (dw > width && dh < height) {

scale = width * 1.0f / dw;

}

// 图片的宽度小于控件的宽度,图片的高度大于空间的高度,我们将其缩小

if (dh > height && dw < width) {

scale = height * 1.0f / dh;

}

// 缩小值

if (dw > width && dh > height) {

scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);

}

// 放大值

if (dw < width && dh < height) {

scale = Math.min(width * 1.0f / dw, height * 1.0f / dh);

}

/**

* 得到了初始化时缩放的比例

*/

mInitScale = scale;

mMaxScale = mInitScale * 4;

mMidScale = mInitScale * 2;

// 将图片移动至控件的中间

int dx = getWidth() / 2 - dw / 2;

int dy = getHeight() / 2 - dh / 2;

mScaleMatrix.postTranslate(dx, dy);

mScaleMatrix.postScale(mInitScale, mInitScale, width / 2,

height / 2);

setImageMatrix(mScaleMatrix);

mOnce = true;

}

}

/**

* 注册OnGlobalLayoutListener这个接口

*/

@Override

protected void onAttachedToWindow() {

super.onAttachedToWindow();

getViewTreeObserver().addOnGlobalLayoutListener(this);

}

/**

* 取消OnGlobalLayoutListener这个接口

*/

@SuppressWarnings("deprecation")

@Override

protected void onDetachedFromWindow() {

super.onDetachedFromWindow();

getViewTreeObserver().removeGlobalOnLayoutListener(this);

}

/**

* 获取当前图片的缩放值

*

* @return

*/

public float getScale() {

float[] values = new float[9];

mScaleMatrix.getValues(values);

return values[Matrix.MSCALE_X];

}

// 缩放区间时initScale maxScale

@Override

public boolean onScale(ScaleGestureDetector detector) {

float scale = getScale();

float scaleFactor = detector.getScaleFactor();

if (getDrawable() == null) {

return true;

}

// 缩放范围的控制

if ((scale < mMaxScale && scaleFactor > 1.0f)

|| (scale > mInitScale && scaleFactor < 1.0f)) {

if (scale * scaleFactor < mInitScale) {

scaleFactor = mInitScale / scale;

}

if (scale * scaleFactor > mMaxScale) {

scale = mMaxScale / scale;

}

// 缩放

mScaleMatrix.postScale(scaleFactor, scaleFactor,

detector.getFocusX(), detector.getFocusY());

checkBorderAndCenterWhenScale();

setImageMatrix(mScaleMatrix);

}

return true;

}

/**

* 获得图片放大缩小以后的宽和高,以及left,right,top,bottom

*

* @return

*/

private RectF getMatrixRectF() {

Matrix matrix = mScaleMatrix;

RectF rectF = new RectF();

Drawable d = getDrawable();

if (d != null) {

rectF.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());

matrix.mapRect(rectF);

}

return rectF;

}

/**

* 在缩放的时候进行边界以及我们的位置的控制

*/

private void checkBorderAndCenterWhenScale() {

RectF rectF = getMatrixRectF();

float deltaX = 0;

float deltaY = 0;

int width = getWidth();

int height = getHeight();

// 缩放时进行边界检测,防止出现白边

if (rectF.width() >= width) {

if (rectF.left > 0) {

deltaX = -rectF.left;

}

if (rectF.right < width) {

deltaX = width - rectF.right;

}

}

if (rectF.height() >= height) {

if (rectF.top > 0) {

deltaY = -rectF.top;

}

if (rectF.bottom < height) {

deltaY = height - rectF.bottom;

}

}

/**

* 如果宽度或高度小于空间的宽或者高,则让其居中

*/

if (rectF.width() < width) {

deltaX = width / 2f - rectF.right + rectF.width() / 2f;

}

if (rectF.height() < height) {

deltaY = height / 2f - rectF.bottom + rectF.height() / 2f;

}

mScaleMatrix.postTranslate(deltaX, deltaY);

}

@Override

public boolean onScaleBegin(ScaleGestureDetector detector) {

return true;

}

@Override

public void onScaleEnd(ScaleGestureDetector detector) {

}

@Override

public boolean onTouch(View v, MotionEvent event) {

if (mGestureDetector.onTouchEvent(event)) {

return true;

}

mScaleGestureDetector.onTouchEvent(event);

float x = 0;

float y = 0;

// 拿到多点触控的数量

int pointerCount = event.getPointerCount();

for (int i = 0; i < pointerCount; i++) {

x += event.getX(i);

y += event.getY(i);

}

x /= pointerCount;

y /= pointerCount;

if (mLastPointerCount != pointerCount) {

isCanDrag = false;

mLastX = x;

mLastY = y;

}

mLastPointerCount = pointerCount;

RectF rectF = getMatrixRectF();

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

if (rectF.width()>getWidth() +0.01|| rectF.height()>getHeight()+0.01) {

if(getParent() instanceof ViewPager)

getParent().requestDisallowInterceptTouchEvent(true);

}

break;

case MotionEvent.ACTION_MOVE:

if (rectF.width()>getWidth()+0.01 || rectF.height()>getHeight()+0.01) {

if(getParent() instanceof ViewPager){

Log.e("---","----+++");

getParent().requestDisallowInterceptTouchEvent(true);

}

}

float dx = x - mLastX;

float dy = y - mLastY;

if (!isCanDrag) {

isCanDrag = isMoveAction(dx, dy);

}

if (isCanDrag) {

if (getDrawable() != null) {

isCheckLeftAndRight = isCheckTopAndBottom = true;

// 如果宽度小于控件宽度,不允许横向移动

if (rectF.width() < getWidth()) {

isCheckLeftAndRight = false;

dx = 0;

}

// 如果高度小于控件高度,不允许纵向移动

if (rectF.height() < getHeight()) {

isCheckTopAndBottom = false;

dy = 0;

}

mScaleMatrix.postTranslate(dx, dy);

checkBorderWhenTranslate();

setImageMatrix(mScaleMatrix);

}

}

mLastX = x;

mLastY = y;

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

mLastPointerCount = 0;

break;

default:

break;

}

return true;

}

/**

* 当移动时进行边界检查

*/

private void checkBorderWhenTranslate() {

RectF rectF = getMatrixRectF();

float deltaX = 0;

float deltaY = 0;

int width = getWidth();

int heigth = getHeight();

if (rectF.top > 0 && isCheckTopAndBottom) {

deltaY = -rectF.top;

}

if (rectF.bottom < heigth && isCheckTopAndBottom) {

deltaY = heigth - rectF.bottom;

}

if (rectF.left > 0 && isCheckLeftAndRight) {

deltaX = -rectF.left;

}

if (rectF.right < width && isCheckLeftAndRight) {

deltaX = width - rectF.right;

}

mScaleMatrix.postTranslate(deltaX, deltaY);

}

/**

* 判断是否是move

*

* @param dx

* @param dy

* @return

*/

private boolean isMoveAction(float dx, float dy) {

return Math.sqrt(dx * dx + dy * dy) > mTouchSlop;

}

}

GlideImageLoader类

package com.dash.xiangqingproject;

import android.content.Context;

import .Uri;

import android.widget.ImageView;

import com.bumptech.glide.Glide;

import com.youth.banner.loader.ImageLoader;

/**

* Created by Dash on /12/9.

*/

public class GlideImageLoader extends ImageLoader {

@Override

public void displayImage(Context context, Object path, ImageView imageView) {

//Glide 加载图片简单用法

Glide.with(context).load((String)path).into(imageView);

}

}

封装DetailBean类

package com.dash.xiangqingproject;

/**

* Created by Dash on /1/17.

*/

public class DetailBean {

/**

* msg :

* seller : {"description":"我是商家15","icon":"http://120.27.23.105/images/icon.png","name":"商家15","productNums":999,"score":5,"sellerid":15}

* code : 0

* data : {"bargainPrice":11800,"createtime":"-10-03T23:53:28","detailUrl":"https://mitem.jd.hk/ware/view.action?wareId=1988853309&cachekey=1acb07a701ece8d2434a6ae7fa6870a1","images":"/n0/jfs/t6130/97/1370670410/180682/1109582a/593276b1Nd81fe723.jpg!q70.jpg|/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7Nbd94ef1f.jpg!q70.jpg|/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7Nbd94ef1f.jpg!q70.jpg|/n0/jfs/t5815/178/2614671118/51656/7f52d137/593276c7N107b725a.jpg!q70.jpg|/n0/jfs/t5878/60/2557817477/30873/4502b606/593276caN5a7d6357.jpg!q70.jpg","itemtype":0,"pid":71,"price":32999,"pscid":40,"salenum":4242,"sellerid":15,"subhead":"购买电脑办公部分商品满1元返火车票5元优惠券(返完即止)","title":"全球购 新款Apple MacBook Pro 苹果笔记本电脑 银色VP2新13英寸Bar i5/8G/256G"}

*/

private String msg;

private SellerBean seller;

private String code;

private DataBean data;

public String getMsg() {

return msg;

}

public void setMsg(String msg) {

this.msg = msg;

}

public SellerBean getSeller() {

return seller;

}

public void setSeller(SellerBean seller) {

this.seller = seller;

}

public String getCode() {

return code;

}

public void setCode(String code) {

this.code = code;

}

public DataBean getData() {

return data;

}

public void setData(DataBean data) {

this.data = data;

}

public static class SellerBean {

/**

* description : 我是商家15

* icon : http://120.27.23.105/images/icon.png

* name : 商家15

* productNums : 999

* score : 5.0

* sellerid : 15

*/

private String description;

private String icon;

private String name;

private int productNums;

private double score;

private int sellerid;

public String getDescription() {

return description;

}

public void setDescription(String description) {

this.description = description;

}

public String getIcon() {

return icon;

}

public void setIcon(String icon) {

this.icon = icon;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getProductNums() {

return productNums;

}

public void setProductNums(int productNums) {

this.productNums = productNums;

}

public double getScore() {

return score;

}

public void setScore(double score) {

this.score = score;

}

public int getSellerid() {

return sellerid;

}

public void setSellerid(int sellerid) {

this.sellerid = sellerid;

}

}

public static class DataBean {

/**

* bargainPrice : 11800.0

* createtime : -10-03T23:53:28

* detailUrl : https://mitem.jd.hk/ware/view.action?wareId=1988853309&cachekey=1acb07a701ece8d2434a6ae7fa6870a1

* images : /n0/jfs/t6130/97/1370670410/180682/1109582a/593276b1Nd81fe723.jpg!q70.jpg|/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7Nbd94ef1f.jpg!q70.jpg|/n0/jfs/t5698/110/2617517836/202970/c9388feb/593276b7Nbd94ef1f.jpg!q70.jpg|/n0/jfs/t5815/178/2614671118/51656/7f52d137/593276c7N107b725a.jpg!q70.jpg|/n0/jfs/t5878/60/2557817477/30873/4502b606/593276caN5a7d6357.jpg!q70.jpg

* itemtype : 0

* pid : 71

* price : 32999.0

* pscid : 40

* salenum : 4242

* sellerid : 15

* subhead : 购买电脑办公部分商品满1元返火车票5元优惠券(返完即止)

* title : 全球购 新款Apple MacBook Pro 苹果笔记本电脑 银色VP2新13英寸Bar i5/8G/256G

*/

private double bargainPrice;

private String createtime;

private String detailUrl;

private String images;

private int itemtype;

private int pid;

private double price;

private int pscid;

private int salenum;

private int sellerid;

private String subhead;

private String title;

public double getBargainPrice() {

return bargainPrice;

}

public void setBargainPrice(double bargainPrice) {

this.bargainPrice = bargainPrice;

}

public String getCreatetime() {

return createtime;

}

public void setCreatetime(String createtime) {

this.createtime = createtime;

}

public String getDetailUrl() {

return detailUrl;

}

public void setDetailUrl(String detailUrl) {

this.detailUrl = detailUrl;

}

public String getImages() {

return images;

}

public void setImages(String images) {

this.images = images;

}

public int getItemtype() {

return itemtype;

}

public void setItemtype(int itemtype) {

this.itemtype = itemtype;

}

public int getPid() {

return pid;

}

public void setPid(int pid) {

this.pid = pid;

}

public double getPrice() {

return price;

}

public void setPrice(double price) {

this.price = price;

}

public int getPscid() {

return pscid;

}

public void setPscid(int pscid) {

this.pscid = pscid;

}

public int getSalenum() {

return salenum;

}

public void setSalenum(int salenum) {

this.salenum = salenum;

}

public int getSellerid() {

return sellerid;

}

public void setSellerid(int sellerid) {

this.sellerid = sellerid;

}

public String getSubhead() {

return subhead;

}

public void setSubhead(String subhead) {

this.subhead = subhead;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

}

}

封装OkHttp3Util_03类

package com.dash.xiangqingproject;

import android.app.Activity;

import android.content.Intent;

import .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;

/**

* Created by Dash on /12/8.

*

* 公共参数封装分为两种方式....source=android,,,appVersion=100

* 一:封装到doGet和doPost方法中

*

*

* 二:封装到拦截器(interceptor):拦截一个请求,然后添加参数进去

*/

public class OkHttp3Util_03 {

/**

* 懒汉 安全 加同步

* 1.私有的静态成员变量 只声明不创建

* 2.私有的构造方法

* 3.提供返回实例的静态方法

*/

private static OkHttpClient okHttpClient = null;

private OkHttp3Util_03() {

}

public static OkHttpClient getInstance() {

if (okHttpClient == null) {

//加同步安全

synchronized (OkHttp3Util_03.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())//添加应用拦截器的方法

.cache(new Cache(sdcache.getAbsoluteFile(), cacheSize))//设置缓存

.build();

}

}

}

return okHttpClient;

}

/**

* get请求

* 参数1 url

* 参数2 回调Callback

*

* oldUrl表示老的地址,,,是没封装公共参数之前的地址....公共参数指的是source=android

*

*/

public static void doGet(String oldUrl, Callback callback) {

//创建OkHttpClient请求对象

OkHttpClient okHttpClient = getInstance();

//创建Request

Request request = new Request.Builder().url(oldUrl).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) {

//创建OkHttpClient请求对象

OkHttpClient okHttpClient = getInstance();

//3.x版本post请求换成FormBody 封装键值对参数

FormBody.Builder builder = new FormBody.Builder();

//遍历集合,,,map集合遍历方式

for (String key : params.keySet()) {

builder.add(key, params.get(key));

}

//创建Request....formBody...new formBody.Builder()...add()....build()

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,Callback callback) {

//创建OkHttpClient请求对象

OkHttpClient okHttpClient = getInstance();

//MultipartBody多功能的请求实体对象,,,formBody只能传表单形式的数据

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(callback);

}

/**

* 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) {

//get请求

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 {

//response.body().string()...json限制是1M大小...byteStream()流的方式

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{

//intercept方法就是拦截的意思....拦截的是一个请求,,,一旦拦截之后可以对请求的参数进行处理

//Chain chain 链条的意思

@Override

public Response intercept(Chain chain) throws IOException {

Log.e("----","拦截器------");

//调用request()方法得到拦截的请求

Request request = chain.request();

//获取请求的方式

String method = request.method();//GET POST

//拦截的请求的路径

String oldUrl = request.url().toString();

//要添加的公共参数...map

Map<String,String> map = new HashMap<>();

map.put("source","android");

if ("GET".equals(method)){

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("?");

}

//添加公共参数....source=android&appVersion=100&

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)){

Log.e("--oldUrl--",oldUrl);

//参数在请求的实体内容上....拿到以前的参数,把以前的参数和公共参数全都添加到请求实体上

RequestBody requestBody = request.body();

if (requestBody instanceof FormBody){//前边是不是后边的子类/实例对象

FormBody oldBody = (FormBody) requestBody;//keywords...page

FormBody.Builder builder = new FormBody.Builder();

//先添加之前的参数

for (int i = 0;i<oldBody.size();i++){

//键值对的形式添加

builder.add(oldBody.name(i),oldBody.value(i));

}

//添加公共参数

for (Map.Entry<String,String> entry: map.entrySet()) {

builder.add(entry.getKey(),entry.getValue());

}

//构建一个新的请求

request = request.newBuilder().url(oldUrl).post(builder.build()).build();

}

}

//执行请求 获取到响应

Response response = chain.proceed(request);

return response;

}

}

}

activity_main.xml布局

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="/apk/res/android"

xmlns:app="/apk/res-auto"

android:orientation="vertical"

xmlns:tools="/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.dash.xiangqingproject.MainActivity">

<android.support.v4.view.ViewPager

android:id="@+id/view_pager"

android:layout_width="match_parent"

android:layout_height="200dp">

</android.support.v4.view.ViewPager>

</LinearLayout>

activity_pic.xml布局

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="/apk/res/android"

xmlns:app="/apk/res-auto"

xmlns:tools="/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.dash.xiangqingproject.PicActivity">

<android.support.v4.view.ViewPager

android:layout_centerInParent="true"

android:id="@+id/view_pager"

android:layout_width="match_parent"

android:layout_height="match_parent">

</android.support.v4.view.ViewPager>

</RelativeLayout>

ic_launcher_foreground.xml

<vector xmlns:android="/apk/res/android"

xmlns:aapt="/aapt"

android:width="108dp"

android:height="108dp"

android:viewportHeight="108"

android:viewportWidth="108">

<path

android:fillType="evenOdd"

android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"

android:strokeColor="#00000000"

android:strokeWidth="1">

<aapt:attr name="android:fillColor">

<gradient

android:endX="78.5885"

android:endY="90.9159"

android:startX="48.7653"

android:startY="61.0927"

android:type="linear">

<item

android:color="#44000000"

android:offset="0.0" />

<item

android:color="#00000000"

android:offset="1.0" />

</gradient>

</aapt:attr>

</path>

<path

android:fillColor="#FFFFFF"

android:fillType="nonZero"

android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"

android:strokeColor="#00000000"

android:strokeWidth="1" />

</vector>

ic_launcher_background.xml

<?xml version="1.0" encoding="utf-8"?>

<vector xmlns:android="/apk/res/android"

android:width="108dp"

android:height="108dp"

android:viewportHeight="108"

android:viewportWidth="108">

<path

android:fillColor="#26A69A"

android:pathData="M0,0h108v108h-108z" />

<path

android:fillColor="#00000000"

android:pathData="M9,0L9,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M19,0L19,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M29,0L29,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M39,0L39,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M49,0L49,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M59,0L59,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M69,0L69,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M79,0L79,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M89,0L89,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M99,0L99,108"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,9L108,9"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,19L108,19"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,29L108,29"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,39L108,39"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,49L108,49"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,59L108,59"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,69L108,69"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,79L108,79"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,89L108,89"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M0,99L108,99"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M19,29L89,29"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M19,39L89,39"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M19,49L89,49"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M19,59L89,59"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M19,69L89,69"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M19,79L89,79"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M29,19L29,89"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M39,19L39,89"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M49,19L49,89"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M59,19L59,89"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M69,19L69,89"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

<path

android:fillColor="#00000000"

android:pathData="M79,19L79,89"

android:strokeColor="#33FFFFFF"

android:strokeWidth="0.8" />

</vector>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。