月考模拟

一些依赖

compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.facebook.fresco:fresco:0.12.0'

compile 'io.reactivex:rxandroid:1.0.1'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile 'com.squareup.retrofit2:converter-scalars:+'
<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" />
android:name=".App"
<activity android:name=".PicActivity"></activity>

    drawable

ic_launcher_background.xml

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/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>


   activity_main.xml

<?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"
   >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#28B8F7">

        <RelativeLayout
            android:layout_width="50dp"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/image_left"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:src="@drawable/left"
                android:layout_centerInParent="true"/>

        </RelativeLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/bzbm"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent"
                android:text="报纸版面"
                android:textColor="#FFFFFF"
                android:textSize="18sp"
                android:layout_marginRight="5dp"
                android:gravity="center_vertical|right"/>

            <TextView
                android:id="@+id/bqml"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent"
                android:text="本期目录"
                android:textColor="#FFFFFF"
                android:textSize="18sp"
                android:layout_marginLeft="5dp"
                android:gravity="center_vertical|left"/>

        </LinearLayout>

        <RelativeLayout
            android:layout_width="50dp"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/image_right"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:src="@drawable/right"
                android:layout_centerInParent="true"/>

        </RelativeLayout>

    </LinearLayout>

    <FrameLayout
        android:id="@+id/frame_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>

</LinearLayout>

   activity_pic.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.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>

fragment_bqml.xml

<?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"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#FFFFFF">

        <TextView
            android:id="@+id/date"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:layout_marginLeft="5dp"
            android:textColor="#28B8F7"
            android:textSize="18dp"
            android:gravity="center_vertical"/>

        <TextView
            android:id="@+id/mldh"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:gravity="center_vertical"
            android:layout_marginRight="5dp"
            android:textColor="#28B8F7"
            android:textSize="18dp"
            android:text="目录导航"/>

    </RelativeLayout>

    <ExpandableListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:groupIndicator="@null">

    </ExpandableListView>

</LinearLayout>

  fragment_bzbm.xml

<?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"
    android:orientation="vertical">

    <TextView
        android:id="@+id/date"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginLeft="5dp"
        android:textColor="#28B8F7"
        android:textSize="18dp"
        android:background="#FFFFFF"
        android:gravity="center_vertical"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

</LinearLayout>

   layout_child.xml

<?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="wrap_content">

    <TextView
        android:id="@+id/child_title"
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:gravity="center_vertical"
        android:layout_marginLeft="20dp"/>

</LinearLayout>

   layout_group.xml


<?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="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:gravity="center_vertical"
        android:background="#CCCCCC">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:src="@drawable/group"
            android:layout_marginLeft="10dp"/>

        <TextView
            android:id="@+id/group_name"
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:gravity="center_vertical"
            android:layout_marginLeft="10dp"/>

    </LinearLayout>

</LinearLayout>


mldh.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:background="#999999"
        android:alpha="0.7">

    </ListView>

</LinearLayout>


 

MainActivity.java
package com.example.dasd.yuekao1;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.dasd.yuekao1.fragment.BQML;
import com.example.dasd.yuekao1.fragment.BZBM;
import com.example.dasd.yuekao1.model.DataDataBean;
import com.example.dasd.yuekao1.util.Api;
import com.example.dasd.yuekao1.util.RetrofitHelper;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.List;

import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageView image_left;
    private TextView bzbm;
    private TextView bqml;
    private ImageView image_right;
    private FrameLayout frame_layout;
    private String str;
    private ArrayList<String> imageUrls;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        hideActionBar();

        switchFragment(0);

        RetrofitHelper.getApiService(Api.BASE_URL)
                .getData(Api.URL, Api.getParams())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        imageUrls = new ArrayList<>();
                        Gson gson = new Gson();
                        DataDataBean dataDataBean = gson.fromJson(s, DataDataBean.class);
                        List<DataDataBean.LayoutsBean> layouts = dataDataBean.getLayouts();
                        for (int i = 0; i < layouts.size(); i++) {
                            imageUrls.add(layouts.get(i).getPicUrl());
                        }
                    }
                });
    }

    private void switchFragment(int index) {
        switch (index) {
            case 0:
                getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, new BZBM()).commit();
                break;
            case 1:
                getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, new BQML()).commit();
                break;
            default:
                break;
        }
    }

    private void hideActionBar() {
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.hide();
        }
    }

    private void initView() {
        image_left = (ImageView) findViewById(R.id.image_left);
        bzbm = (TextView) findViewById(R.id.bzbm);
        bqml = (TextView) findViewById(R.id.bqml);
        image_right = (ImageView) findViewById(R.id.image_right);
        frame_layout = (FrameLayout) findViewById(R.id.frame_layout);

        image_left.setOnClickListener(this);
        bzbm.setOnClickListener(this);
        bqml.setOnClickListener(this);
        image_right.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.image_left:
                str.contains("error");
                break;
            case R.id.bzbm:
                switchFragment(0);
                break;
            case R.id.bqml:
                switchFragment(1);
                break;
            case R.id.image_right:
                Intent intent = new Intent(MainActivity.this, PicActivity.class);
                intent.putStringArrayListExtra("list", imageUrls);
                startActivity(intent);
                break;
            default:
                break;
        }
    }
}
             

            App.java
package com.example.dasd.yuekao1;

import android.app.Application;

import com.example.dasd.yuekao1.util.CrashHandler;
import com.example.dasd.yuekao1.util.ImagePipelineConfigUtils;
import com.facebook.drawee.backends.pipeline.Fresco;

/**
 * Created by yujie on 2018/1/18.
 */

public class App extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        Fresco.initialize(this, ImagePipelineConfigUtils.getDefaultImagePipelineConfig(this));
        CrashHandler.getInstace().init(this);
    }
}

PicActivity.java
package com.example.dasd.yuekao1;

import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;

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

        hideActionBar();

        viewPager = (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();
                }
            });
        }

    }

    private void hideActionBar() {
       ActionBar actionBar = getSupportActionBar();
       if (actionBar != null) {
          actionBar.hide();
       }
    }

}

           ZoomImageView.java
package com.example.dasd.yuekao1;

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.OnGlobalLayoutListener;
import android.widget.ImageView;

@SuppressLint("AppCompatCustomView")
public class ZoomImageView extends ImageView implements OnGlobalLayoutListener, OnScaleGestureListener, 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@lzt.com.cn
     *
     */
    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;
    }
}

base包
BaseActivity.java
package com.example.dasd.yuekao1.base;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

public abstract class BaseActivity<IPre, P extends BasePresenter<IPre>> extends AppCompatActivity{
    public P presenter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(setLayoutResID());

        presenter = initPresenter();

        presenter.attach((IPre) this);

        initView();

        initData();
    }

    public abstract int setLayoutResID();

    public abstract P initPresenter();

    public abstract void initView();

    public abstract void initData();
}

base包
BaseFragment.java
package com.example.dasd.yuekao1.base;

import android.os.Bundle;
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<IPre, P extends BasePresenter<IPre>> extends Fragment{
    public P presenter;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return createView(inflater, container, savedInstanceState);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        presenter = initPresenter();
        presenter.attach((IPre) this);

        initData();
    }

    protected abstract View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);

    protected abstract P initPresenter();

    protected abstract void initData();
}

base包
BasePresenter.java
package com.example.dasd.yuekao1.base;

public abstract class BasePresenter<IPre> {
    public IPre iPresenter;

    public void attach(IPre iPresenter){
        this.iPresenter = iPresenter;
      initModel();
    }

    public void detach(){
        if(iPresenter != null){
            iPresenter = null;
        }
    }

    protected abstract void initModel();
}

fragment包
BQML.java

package com.example.dasd.yuekao1.fragment;

import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

import com.example.dasd.yuekao1.R;
import com.example.dasd.yuekao1.base.BaseFragment;
import com.example.dasd.yuekao1.model.DataDataBean;
import com.example.dasd.yuekao1.presenter.IPresenter;
import com.example.dasd.yuekao1.presenter.PresenterImpl;
import com.example.dasd.yuekao1.util.Api;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by yujie on 2018/1/18.
 */

public class BQML extends BaseFragment<IPresenter, PresenterImpl> implements IPresenter, View.OnClickListener {

    private TextView date_text;
    private TextView mldh;
    private ExpandableListView listView;
    private List<DataDataBean.LayoutsBean> layouts;
    private PopupWindow popupWindow;
    private List<String> dhs;

    @Override
    protected View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_bqml, container, false);
        initView(view);
        return view;
    }

    private void initView(View view) {
        date_text = (TextView) view.findViewById(R.id.date);
        mldh = (TextView) view.findViewById(R.id.mldh);
        listView = (ExpandableListView) view.findViewById(R.id.list_view);

        mldh.setOnClickListener(this);
        listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
                Toast.makeText(getContext(), layouts.get(i).getList().get(i1).getTitle(), Toast.LENGTH_SHORT).show();
                return false;
            }
        });
    }

    @Override
    protected PresenterImpl initPresenter() {
        return new PresenterImpl();
    }

    @Override
    protected void initData() {
        presenter.getData(Api.BASE_URL, Api.URL, Api.getParams());
    }

    @Override
    public void onPreSuccess(DataDataBean dataDataBean) {
        dhs = new ArrayList<>();
        date_text.setText(dataDataBean.getDate());
        layouts = dataDataBean.getLayouts();
        listView.setAdapter(new ELAdapter());
        for (int i = 0; i < layouts.size(); i++) {
            dhs.add(layouts.get(i).getName());
            listView.expandGroup(i);
        }
    }

    @Override
    public void onPreError() {

    }

    @Override
    public void onClick(View view) {
        View view1 = LayoutInflater.from(getContext()).inflate(R.layout.mldh, null, false);
        ListView list = (ListView) view1.findViewById(R.id.list_view);
        list.setAdapter(new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, dhs));
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                listView.setSelectedGroup(i);
                popupWindow.dismiss();
            }
        });
        popupWindow = new PopupWindow(view1,
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.setFocusable(true);
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        popupWindow.setOutsideTouchable(true);
        popupWindow.showAsDropDown(mldh);
    }

    class ELAdapter extends BaseExpandableListAdapter{


        @Override
        public int getGroupCount() {
            return layouts.size();
        }

        @Override
        public int getChildrenCount(int i) {
            return layouts.get(i).getList().size();
        }

        @Override
        public Object getGroup(int i) {
            return layouts.get(i);
        }

        @Override
        public Object getChild(int i, int i1) {
            return layouts.get(i).getList().get(i1).getTitle();
        }

        @Override
        public long getGroupId(int i) {
            return i;
        }

        @Override
        public long getChildId(int i, int i1) {
            return i1;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
            GroupViewHolder holder;
            if(view == null){
                view = View.inflate(getContext(), R.layout.layout_group, null);
                holder = new GroupViewHolder();
                holder.group_name = (TextView) view.findViewById(R.id.group_name);
                view.setTag(holder);
            }else{
                holder = (GroupViewHolder) view.getTag();
            }

            holder.group_name.setText(layouts.get(i).getName());

            return view;
        }

        @Override
        public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
            ChildViewHolder holder;
            if(view == null){
                view = View.inflate(getContext(), R.layout.layout_child, null);
                holder = new ChildViewHolder();
                holder.child_title = (TextView) view.findViewById(R.id.child_title);
                view.setTag(holder);
            }else{
                holder = (ChildViewHolder) view.getTag();
            }

            holder.child_title.setText(layouts.get(i).getList().get(i1).getTitle());

            return view;
        }

        @Override
        public boolean isChildSelectable(int i, int i1) {
            return true;
        }

        class GroupViewHolder{
            TextView group_name;
        }

        class ChildViewHolder{
            TextView child_title;
        }
    }
}


fragment包
BZBM.java
package com.example.dasd.yuekao1.fragment;

import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.dasd.yuekao1.R;
import com.example.dasd.yuekao1.base.BaseFragment;
import com.example.dasd.yuekao1.model.DataDataBean;
import com.example.dasd.yuekao1.presenter.IPresenter;
import com.example.dasd.yuekao1.presenter.PresenterImpl;
import com.example.dasd.yuekao1.util.Api;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.backends.pipeline.PipelineDraweeController;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import java.util.List;

/**
 * Created by yujie on 2018/1/18.
 */

public class BZBM extends BaseFragment<IPresenter, PresenterImpl> implements IPresenter {

    private TextView date_text;
    private ViewPager viewPager;
    private List<DataDataBean.LayoutsBean> layouts;

    @Override
    protected View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_bzbm, container, false);
        initView(view);
        return view;
    }

    private void initView(View view) {
        date_text = (TextView) view.findViewById(R.id.date);
        viewPager = (ViewPager) view.findViewById(R.id.view_pager);
    }

    @Override
    protected PresenterImpl initPresenter() {
        return new PresenterImpl();
    }

    @Override
    protected void initData() {
        presenter.getData(Api.BASE_URL, Api.URL, Api.getParams());
    }

    @Override
    public void onPreSuccess(DataDataBean dataDataBean) {
        layouts = dataDataBean.getLayouts();
        date_text.setText(dataDataBean.getDate());
        viewPager.setAdapter(new VPAdapter());
    }

    @Override
    public void onPreError() {

    }

    class VPAdapter extends PagerAdapter{

        @Override
        public int getCount() {
            return layouts.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            SimpleDraweeView simpleDraweeView = new SimpleDraweeView(getActivity());
            simpleDraweeView.setAspectRatio((float) 1);
            //使用控件,并添加到布局中
            // 图片的地址
            Uri uri = Uri.parse(layouts.get(position).getPicUrl());
            // 图片的请求
            ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                    .build();
            // 加载图片的控制
            PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
                    .setOldController(simpleDraweeView.getController())
                    .setImageRequest(request)
                    .build();
            simpleDraweeView.setBackgroundColor(Color.WHITE);
            GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources());
            GenericDraweeHierarchy FIT_XY = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY).build();
            simpleDraweeView.setHierarchy(FIT_XY);
            // 加载图片
            simpleDraweeView.setController(controller);
            container.addView(simpleDraweeView);
            return simpleDraweeView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }

}

model包
DataDataBean.java
package com.example.dasd.yuekao1.model;

import java.util.List;

/**
 * Created by yujie on 2018/1/18.
 */

public class DataDataBean {

    /**
     * version : 0
     * layouts : [{"id":225823,"name":"旅游报01版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/d9f405e7-2a7e-4459-a6e9-324e41f31927.jpg","height":2009,"width":1259,"mapping":[{"mapping":["66.617056%,82.362460%","98.118145%,82.362460%","98.118145%,66.181230%","66.617056%,66.181230%"],"articleID":"2228451"},{"mapping":["1.807440%,79.288026%","63.776794%,79.288026%","63.776794%,58.899676%","1.807440%,58.899676%"],"articleID":"2228452"},{"mapping":["67.649879%,63.430421%","97.085322%,63.430421%","97.085322%,49.029126%","67.649879%,49.029126%"],"articleID":"2228453"},{"mapping":["97.085322%,47.087379%","67.649879%,47.087379%","67.649879%,36.245955%","67.649879%,35.436893%","67.649879%,35.436893%","67.649879%,28.640777%","74.621431%,28.640777%","75.137842%,27.993528%","75.137842%,22.977346%","89.597359%,22.977346%","89.597359%,27.993528%","97.085322%,28.802589%"],"articleID":"2228454"},{"mapping":["1.807440%,54.045307%","64.035000%,54.045307%","64.035000%,17.961165%","1.807440%,17.961165%"],"articleID":"2228455"},{"mapping":["58.096270%,15.210356%","98.118145%,15.210356%","98.118145%,2.103560%","58.096270%,2.103560%"],"articleID":"2228456"}],"list":[{"id":2228451,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228451.json?v=1504073111","title":"医疗旅游服务产业成重要方向","version":1504073111,"pic1":""},{"id":2228452,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228452.json?v=1504073111","title":"内蒙古以全域旅游之笔绘行业发展蓝图","version":1504073111,"pic1":""},{"id":2228453,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228453.json?v=1504073112","title":"城市旅游","version":1504073112,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/baa4058e-d021-4e6a-b515-d1631976a5b1.jpg"},{"id":2228454,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228454.json?v=1504073113","title":"大词汇文化旅游","version":1504073113,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/715b3468-93ef-4e60-8730-ec00a2002de0.jpg"},{"id":2228455,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228455.json?v=1504073115","title":"澳大利亚全国旅游会议首次在华召开","version":1504073115,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/b46177be-afcf-4aa3-8f89-46a4f3f051b3.jpg"},{"id":2228456,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228456.json?v=1504073115","title":"塞罕坝:践行\u201c两山\u201d理论发展生态旅游","version":1504073115,"pic1":""}]},{"id":225824,"name":"旅游报04版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/a5e3736e-d71b-4782-864c-0fc21b48c179.jpg","height":2009,"width":1259,"mapping":[{"mapping":["67.649879%,69.255663%","67.649879%,72.815534%","98.118145%,72.815534%","98.118145%,69.255663%","67.649879%,69.255663%","76.945282%,67.637540%","76.945282%,68.608414%","89.080947%,68.608414%","89.080947%,67.637540%","76.945282%,67.637540%"],"articleID":"2228458"},{"mapping":["67.649879%,62.459547%","67.649879%,66.666667%","98.118145%,66.666667%","98.118145%,62.459547%","67.649879%,62.459547%","78.494516%,60.679612%","78.494516%,61.650485%","89.080947%,61.650485%","89.080947%,60.679612%","78.494516%,60.679612%"],"articleID":"2228459"},{"mapping":["67.649879%,55.501618%","67.649879%,59.708738%","98.118145%,59.708738%","98.118145%,55.501618%","67.649879%,55.501618%","75.137842%,53.721683%","75.137842%,54.530744%","90.888387%,54.530744%","90.888387%,53.721683%","75.137842%,53.721683%"],"articleID":"2228460"},{"mapping":["67.649879%,43.042071%","98.118145%,43.042071%","98.118145%,9.385113%","67.649879%,9.385113%"],"articleID":"2228461"},{"mapping":["64.809617%,72.815534%","1.807440%,72.815534%","1.807440%,46.601942%","1.807440%,36.245955%","1.807440%,9.546926%","64.809617%,9.546926%","64.809617%,13.106796%","64.809617%,24.110032%"],"articleID":"2228462"}],"list":[{"id":2228458,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228458.json?v=1504073120","title":"智利:Puyuhuapi","version":1504073120,"pic1":""},{"id":2228459,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228459.json?v=1504073120","title":"土耳其:布尔萨","version":1504073120,"pic1":""},{"id":2228460,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228460.json?v=1504073120","title":"哥斯达黎加:阿雷纳尔","version":1504073120,"pic1":""},{"id":2228462,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228462.json?v=1504073131","title":"港企珠海御温泉:20年专注一件事","version":1504073131,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/c886ae48-4c76-4969-96d9-eb13733cd068.jpg"}]},{"id":225825,"name":"旅游报05版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/43532b57-0c1c-4a8c-9404-6b5f150ee069.jpg","height":2009,"width":1259,"mapping":[{"mapping":["26.595181%,92.394822%","97.859939%,92.394822%","97.859939%,44.822006%","26.595181%,44.822006%"],"articleID":"2228463"},{"mapping":["3.873085%,92.394822%","22.205685%,92.394822%","22.205685%,47.087379%","3.873085%,47.087379%"],"articleID":"2228464"}],"list":[{"id":2228463,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228463.json?v=1504073142","title":"晒盐的女人","version":1504073142,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/1ddf6da0-f25b-4233-9350-4ac9f16225a6.jpg"},{"id":2228464,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228464.json?v=1504073144","title":"茶马驿镇","version":1504073144,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/9fb35060-5819-465d-85ec-525804fd6936.jpg"}]},{"id":225826,"name":"旅游报06版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/3bcadbec-e108-4b7d-84c8-31873b9349c7.jpg","height":2009,"width":1259,"mapping":[{"mapping":["2.065645%,94.336570%","97.859939%,94.336570%","97.859939%,52.750809%","2.065645%,52.750809%"],"articleID":"2228466"},{"mapping":["97.859939%,49.838188%","2.065645%,49.838188%","2.065645%,26.537217%","2.065645%,16.666667%","2.065645%,5.663430%","97.859939%,5.663430%"],"articleID":"2228467"}],"list":[{"id":2228466,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228466.json?v=1504073159","title":"高原至味","version":1504073159,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/3bb5c7b8-e1c9-4045-9da7-3a2abae05746.jpg"},{"id":2228467,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228467.json?v=1504073167","title":"湖畔香巴拉","version":1504073167,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/613f42c9-49e1-4731-aae1-b92ad55a5a51.jpg"}]},{"id":225827,"name":"旅游报07版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/5bde9f8d-37a4-4a9a-b7cb-8ed880707dff.jpg","height":2009,"width":1259,"mapping":[{"mapping":["2.323851%,94.336570%","97.859939%,94.336570%","97.859939%,50.970874%","2.323851%,50.970874%"],"articleID":"2228469"},{"mapping":["2.065645%,48.058252%","97.859939%,48.058252%","97.859939%,5.663430%","2.065645%,5.663430%"],"articleID":"2228470"}],"list":[{"id":2228469,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228469.json?v=1504073178","title":"\u201c百里挑一\u201d之城","version":1504073178,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/6e510dec-fd75-4728-b2bf-ae2d97a46cfe.jpg"},{"id":2228470,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228470.json?v=1504073185","title":"酥油茶和藏香鸡","version":1504073185,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/4bf8b082-16da-494c-8d3d-c6596fd5bbd0.jpg"}]},{"id":225828,"name":"旅游报08版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/2b483913-0c4e-443f-a90e-00c86220db64.jpg","height":2009,"width":1259,"mapping":[{"mapping":["75.654254%,87.702265%","95.536088%,87.702265%","95.536088%,6.634304%","75.654254%,6.634304%"],"articleID":"2228471"},{"mapping":["71.264758%,94.336570%","2.065645%,94.336570%","2.065645%,6.634304%","71.264758%,6.634304%","71.264758%,64.563107%","71.264758%,73.139159%","71.264758%,73.786408%","71.264758%,81.877023%"],"articleID":"2228472"}],"list":[{"id":2228471,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228471.json?v=1504073192","title":"无关风月","version":1504073192,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/a55bd6a1-e833-4422-bdaf-70f3d1ea77d0.jpg"},{"id":2228472,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228472.json?v=1504073208","title":"张荣强:将版刻年画进行到底","version":1504073208,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/c5e962d6-8f5c-4dd2-8ccf-3eea14aefb78.jpg"}]},{"id":225829,"name":"旅游报09版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/d9400602-220e-4093-96ab-0dfa812c5a53.jpg","height":2009,"width":1259,"mapping":[{"mapping":["98.118145%,95.954693%","1.807440%,95.954693%","1.807440%,95.792880%","1.807440%,61.650485%","1.807440%,48.705502%","1.807440%,42.233010%","1.807440%,4.854369%","98.118145%,4.854369%","98.118145%,67.637540%","98.118145%,95.792880%"],"articleID":"2228473"}],"list":[{"id":2228473,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228473.json?v=1504073215","title":"旅游业持续井喷,发展红利惠","version":1504073215,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/54e2ee51-17fd-4949-bb61-5777a83613eb.jpg"}]},{"id":225830,"name":"旅游报10版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/5839325f-83c8-4380-aedf-cffaaa459ada.jpg","height":2009,"width":1259,"mapping":[{"mapping":["1.807440%,95.954693%","54.739597%,95.954693%","54.739597%,39.644013%","1.807440%,39.644013%"],"articleID":"2228474"},{"mapping":["59.387298%,95.954693%","98.376350%,95.954693%","98.376350%,36.731392%","59.387298%,36.731392%"],"articleID":"2228475"},{"mapping":["1.807440%,37.216828%","98.118145%,37.216828%","98.118145%,4.854369%","1.807440%,4.854369%"],"articleID":"2228476"}],"list":[{"id":2228474,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228474.json?v=1504073229","title":"一个渔港一片海","version":1504073229,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/462ee057-7d91-4196-8c4e-6a448a9e22ce.jpg"},{"id":2228475,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228475.json?v=1504073236","title":"石塘\u2014\u2014","version":1504073236,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/d79493ed-5664-4568-b6ad-ff3c5a6bf301.jpg"},{"id":2228476,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228476.json?v=1504073241","title":"一个渔港一片海一缕阳光一座城","version":1504073241,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/ae3a8f37-37f5-4de6-9291-cbcd2170718f.jpg"}]},{"id":225831,"name":"旅游报11版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/ada8cc40-e084-45db-9586-b813b6e887e9.jpg","height":2009,"width":1259,"mapping":[{"mapping":["75.912459%,83.818770%","55.772419%,83.818770%","55.772419%,49.190939%","55.772419%,48.381877%","55.772419%,47.087379%","75.912459%,47.087379%"],"articleID":"2228477"},{"mapping":["98.118145%,81.553398%","81.334778%,81.553398%","81.334778%,39.482201%","81.334778%,38.673139%","81.334778%,37.378641%","98.118145%,37.378641%"],"articleID":"2228478"},{"mapping":["31.501089%,77.831715%","50.608306%,77.831715%","50.608306%,36.893204%","31.501089%,36.893204%"],"articleID":"2228479"},{"mapping":["7.229758%,67.313916%","27.369798%,67.313916%","27.369798%,38.025890%","7.229758%,38.025890%"],"articleID":"2228480"},{"mapping":["1.807440%,35.113269%","98.118145%,35.113269%","98.118145%,4.854369%","1.807440%,4.854369%"],"articleID":"2228481"}],"list":[{"id":2228479,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228479.json?v=1504073246","title":"杭州旅游全域化成效初显","version":1504073246,"pic1":""},{"id":2228480,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228480.json?v=1504073246","title":"杭州旅游精准发力","version":1504073246,"pic1":""},{"id":2228481,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228481.json?v=1504073246","title":"向国际重要的旅游休闲中心奋力迈进","version":1504073246,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/6fc97c07-7904-41b0-b208-97f93cb7bff8.jpg"}]},{"id":225832,"name":"旅游报12版","date":"2017-08-30","picUrl":"https://img.newaircloud.com/xkycs/paper/201708/30/9f0c9442-b20f-43d5-b000-88a3eaa6264c.jpg","height":2009,"width":1259,"mapping":[{"mapping":["2.323851%,94.498382%","97.601734%,94.498382%","97.601734%,81.715210%","2.323851%,81.715210%"],"articleID":"2228482"},{"mapping":["69.457318%,78.802589%","96.827117%,78.802589%","96.827117%,69.579288%","69.457318%,69.579288%"],"articleID":"2228483"},{"mapping":["66.100645%,79.288026%","19.365423%,79.288026%","19.365423%,72.168285%","19.365423%,65.048544%","19.365423%,63.592233%","66.100645%,63.592233%","66.100645%,65.533981%"],"articleID":"2228484"},{"mapping":["69.457318%,68.608414%","96.827117%,68.608414%","96.827117%,58.737864%","69.457318%,58.737864%"],"articleID":"2228485"},{"mapping":["19.623629%,61.974110%","65.842439%,61.974110%","65.842439%,51.456311%","19.623629%,51.456311%"],"articleID":"2228486"},{"mapping":["69.457318%,57.605178%","96.827117%,57.605178%","96.827117%,46.278317%","69.457318%,46.278317%"],"articleID":"2228487"},{"mapping":["69.199113%,44.983819%","96.827117%,44.983819%","96.827117%,34.304207%","69.199113%,34.304207%"],"articleID":"2228488"},{"mapping":["3.356673%,78.802589%","15.750544%,78.802589%","15.750544%,28.155340%","3.356673%,28.155340%"],"articleID":"2228489"},{"mapping":["19.365423%,49.514563%","66.100645%,49.514563%","66.100645%,27.508091%","19.365423%,27.508091%"],"articleID":"2228490"},{"mapping":["69.457318%,33.333333%","96.827117%,33.333333%","96.827117%,21.035599%","69.457318%,21.035599%"],"articleID":"2228491"},{"mapping":["69.457318%,19.579288%","96.827117%,19.579288%","96.827117%,8.252427%","69.457318%,8.252427%"],"articleID":"2228492"},{"mapping":["2.323851%,25.728155%","65.842439%,25.728155%","65.842439%,5.987055%","2.323851%,5.987055%"],"articleID":"2228493"}],"list":[{"id":2228482,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228482.json?v=1504073251","title":"中国肥城第十届金秋品桃节启动","version":1504073251,"pic1":""},{"id":2228483,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228483.json?v=1504073251","title":"首届复圣茶器文化展精品云集","version":1504073251,"pic1":""},{"id":2228484,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228484.json?v=1504073252","title":"骑着摩拜去膜拜时尚情怀融入传统文化","version":1504073252,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/9c88220a-7e98-40c0-9f51-06d275825851.jpg"},{"id":2228485,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228485.json?v=1504073252","title":"齐河将建温泉度假小镇","version":1504073252,"pic1":""},{"id":2228486,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228486.json?v=1504073252","title":"枣庄薛城:红色文化带动全域旅游发展","version":1504073252,"pic1":""},{"id":2228487,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228487.json?v=1504073252","title":"青岛城阳多措并举激发旅游新动能","version":1504073252,"pic1":""},{"id":2228488,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228488.json?v=1504073252","title":"东营·利津綦家嘴迎来《我是大明星》","version":1504073252,"pic1":""},{"id":2228489,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228489.json?v=1504073252","title":"短讯","version":1504073252,"pic1":""},{"id":2228490,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228490.json?v=1504073254","title":"第四届香草文化旅游节活动丰富","version":1504073254,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/da11bcb4-622e-4020-891c-ad0eae01dcf9.jpg"},{"id":2228491,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228491.json?v=1504073254","title":"珠光宝气\u201c闪耀\u201d泰安","version":1504073254,"pic1":""},{"id":2228492,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228492.json?v=1504073255","title":"2017黄河口公路自行车赛下月举办","version":1504073255,"pic1":""},{"id":2228493,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228493.json?v=1504073257","title":"\u201c山东好礼\u201d出新品","version":1504073257,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/b1ea017c-7596-4e83-9dc8-a40bc0bfd825.jpg"}]}]
     * date : 2017-08-30
     */

    private int version;
    private String date;
    private List<LayoutsBean> layouts;

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public List<LayoutsBean> getLayouts() {
        return layouts;
    }

    public void setLayouts(List<LayoutsBean> layouts) {
        this.layouts = layouts;
    }

    public static class LayoutsBean {
        /**
         * id : 225823
         * name : 旅游报01版
         * date : 2017-08-30
         * picUrl : https://img.newaircloud.com/xkycs/paper/201708/30/d9f405e7-2a7e-4459-a6e9-324e41f31927.jpg
         * height : 2009
         * width : 1259
         * mapping : [{"mapping":["66.617056%,82.362460%","98.118145%,82.362460%","98.118145%,66.181230%","66.617056%,66.181230%"],"articleID":"2228451"},{"mapping":["1.807440%,79.288026%","63.776794%,79.288026%","63.776794%,58.899676%","1.807440%,58.899676%"],"articleID":"2228452"},{"mapping":["67.649879%,63.430421%","97.085322%,63.430421%","97.085322%,49.029126%","67.649879%,49.029126%"],"articleID":"2228453"},{"mapping":["97.085322%,47.087379%","67.649879%,47.087379%","67.649879%,36.245955%","67.649879%,35.436893%","67.649879%,35.436893%","67.649879%,28.640777%","74.621431%,28.640777%","75.137842%,27.993528%","75.137842%,22.977346%","89.597359%,22.977346%","89.597359%,27.993528%","97.085322%,28.802589%"],"articleID":"2228454"},{"mapping":["1.807440%,54.045307%","64.035000%,54.045307%","64.035000%,17.961165%","1.807440%,17.961165%"],"articleID":"2228455"},{"mapping":["58.096270%,15.210356%","98.118145%,15.210356%","98.118145%,2.103560%","58.096270%,2.103560%"],"articleID":"2228456"}]
         * list : [{"id":2228451,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228451.json?v=1504073111","title":"医疗旅游服务产业成重要方向","version":1504073111,"pic1":""},{"id":2228452,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228452.json?v=1504073111","title":"内蒙古以全域旅游之笔绘行业发展蓝图","version":1504073111,"pic1":""},{"id":2228453,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228453.json?v=1504073112","title":"城市旅游","version":1504073112,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/baa4058e-d021-4e6a-b515-d1631976a5b1.jpg"},{"id":2228454,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228454.json?v=1504073113","title":"大词汇文化旅游","version":1504073113,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/715b3468-93ef-4e60-8730-ec00a2002de0.jpg"},{"id":2228455,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228455.json?v=1504073115","title":"澳大利亚全国旅游会议首次在华召开","version":1504073115,"pic1":"https://img.newaircloud.com/xkycs/paper/201708/30/b46177be-afcf-4aa3-8f89-46a4f3f051b3.jpg"},{"id":2228456,"curl":"https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228456.json?v=1504073115","title":"塞罕坝:践行\u201c两山\u201d理论发展生态旅游","version":1504073115,"pic1":""}]
         */

        private int id;
        private String name;
        private String date;
        private String picUrl;
        private int height;
        private int width;
        private List<MappingBean> mapping;
        private List<ListBean> list;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDate() {
            return date;
        }

        public void setDate(String date) {
            this.date = date;
        }

        public String getPicUrl() {
            return picUrl;
        }

        public void setPicUrl(String picUrl) {
            this.picUrl = picUrl;
        }

        public int getHeight() {
            return height;
        }

        public void setHeight(int height) {
            this.height = height;
        }

        public int getWidth() {
            return width;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        public List<MappingBean> getMapping() {
            return mapping;
        }

        public void setMapping(List<MappingBean> mapping) {
            this.mapping = mapping;
        }

        public List<ListBean> getList() {
            return list;
        }

        public void setList(List<ListBean> list) {
            this.list = list;
        }

        public static class MappingBean {
            /**
             * mapping : ["66.617056%,82.362460%","98.118145%,82.362460%","98.118145%,66.181230%","66.617056%,66.181230%"]
             * articleID : 2228451
             */

            private String articleID;
            private List<String> mapping;

            public String getArticleID() {
                return articleID;
            }

            public void setArticleID(String articleID) {
                this.articleID = articleID;
            }

            public List<String> getMapping() {
                return mapping;
            }

            public void setMapping(List<String> mapping) {
                this.mapping = mapping;
            }
        }

        public static class ListBean {
            /**
             * id : 2228451
             * curl : https://oss.newaircloud.com/xkycs/paper/article/201708/30/c2228451.json?v=1504073111
             * title : 医疗旅游服务产业成重要方向
             * version : 1504073111
             * pic1 :
             */

            private int id;
            private String curl;
            private String title;
            private int version;
            private String pic1;

            public int getId() {
                return id;
            }

            public void setId(int id) {
                this.id = id;
            }

            public String getCurl() {
                return curl;
            }

            public void setCurl(String curl) {
                this.curl = curl;
            }

            public String getTitle() {
                return title;
            }

            public void setTitle(String title) {
                this.title = title;
            }

            public int getVersion() {
                return version;
            }

            public void setVersion(int version) {
                this.version = version;
            }

            public String getPic1() {
                return pic1;
            }

            public void setPic1(String pic1) {
                this.pic1 = pic1;
            }
        }
    }
}

model包
创建IModel接口
package com.example.dasd.yuekao1.model;

/**
 * Created by yujie on 2018/1/18.
 */

public interface IModel {
    void onModelSuccess(DataDataBean dataDataBean);
    void onModelError();
}

model包
Model.java
package com.example.dasd.yuekao1.model;

import com.example.dasd.yuekao1.util.RetrofitHelper;
import com.google.gson.Gson;

import java.util.Map;

import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by yujie on 2018/1/18.
 */

public class Model {
    private IModel iModel;

    public Model(IModel iModel) {
        this.iModel = iModel;
    }

    public void getData(String baseUrl, String url, Map<String, String> params){
        RetrofitHelper.getApiService(baseUrl)
                .getData(url, params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        iModel.onModelError();
                    }

                    @Override
                    public void onNext(String s) {
                        Gson gson = new Gson();
                        DataDataBean dataDataBean = gson.fromJson(s, DataDataBean.class);
                        iModel.onModelSuccess(dataDataBean);
                    }
                });
    }
}

presentere包
实现IPresenter接口
package com.example.dasd.yuekao1.presenter;


import com.example.dasd.yuekao1.model.DataDataBean;

/**
 * Created by yujie on 2018/1/18.
 */

public interface IPresenter {
    void onPreSuccess(DataDataBean dataDataBean);
    void onPreError();
}


presentere包
PresenterImpl.java
package com.example.dasd.yuekao1.presenter;


import com.example.dasd.yuekao1.base.BasePresenter;
import com.example.dasd.yuekao1.model.DataDataBean;
import com.example.dasd.yuekao1.model.IModel;
import com.example.dasd.yuekao1.model.Model;

import java.util.Map;

/**
 * Created by yujie on 2018/1/18.
 */

public class PresenterImpl extends BasePresenter<IPresenter> implements IModel {
    private Model model;

    @Override
    protected void initModel() {
        model = new Model(this);
    }

    public void getData(String baseUrl, String url, Map<String, String> params){
        model.getData(baseUrl, url, params);
    }

    @Override
    public void onModelSuccess(DataDataBean dataDataBean) {
        iPresenter.onPreSuccess(dataDataBean);
    }

    @Override
    public void onModelError() {
        iPresenter.onPreError();
    }
}


util包
Api.java
package com.example.dasd.yuekao1.util;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by yujie on 2018/1/18.
 */

public class Api {
    //http://h5test.newaircloud.com/api/getLayouts?sid=xkycs&cid=10024&date=
    public static final String BASE_URL = "http://h5test.newaircloud.com/api/";
    public static final String URL = "getLayouts";
    public static Map<String, String> getParams(){
        Map<String, String> params = new HashMap<>();
        params.put("sid", "xkycs");
        params.put("cid", "10024");
        return params;
    }
}

util包
ApiService接口
package com.example.dasd.yuekao1.util;

import java.util.Map;

import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.QueryMap;
import retrofit2.http.Url;
import rx.Observable;

/**
 * Created by yujie on 2018/1/18.
 */

public interface ApiService {
    @GET
    Observable<String> getData(@Url String url);

    @GET
    Observable<String> getData(@Url String url, @QueryMap Map<String, String> params);

    @FormUrlEncoded
    @POST
    Observable<String> postData(@Url String url);

    @FormUrlEncoded
    @POST
    Observable<String> postData(@Url String url, @FieldMap Map<String, String> params);
}


util包
CrashHandler.java
package com.example.dasd.yuekao1.util;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.Looper;
import android.os.Process;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Created by Dash on 2017/12/7.
 */
public class CrashHandler implements Thread.UncaughtExceptionHandler {
    private static CrashHandler crashHandler;
    private Context context;
    private Thread.UncaughtExceptionHandler defaultHandler;
    //存日志文件的目录(文件夹)
    private File logDir = new File(Environment.getExternalStorageDirectory(),"error");
    //时间格式化
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS", Locale.CHINA);

    /**
     * 对外提供获取实例对象的方法....单例模式
     * @return
     */
    public static CrashHandler getInstace(){
        if (crashHandler == null){
            synchronized (CrashHandler.class){
                if (crashHandler == null){
                    crashHandler = new CrashHandler();
                }
            }
        }

        return crashHandler;
    }

    /**
     * 初始化的时候.....
     * @param context
     */
    public void init(Context context){
        this.context = context;

        //先拿到系统默认的异常处理器
        defaultHandler = Thread.getDefaultUncaughtExceptionHandler();

        //设置当前作为我们处理异常的处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 当异常发生的时候会自动调用uncaughtException方法
     * @param thread
     * @param throwable
     */
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        //自己没有处理异常,交给系统来处理
        if (!handlerException(throwable) && defaultHandler != null){
            defaultHandler.uncaughtException(thread,throwable);
        }else {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //否则自己处理了异常....上传服务器
            uploadLogToServer();
            //结束进程 退出程序
            Process.killProcess(Process.myPid());//杀死应用的进程
            //非正常退出应用....0表示正常退出,,,非0表示不正常
            System.exit(10);
        }
    }

    /**
     * 上传文件到服务器
     */
    private void uploadLogToServer() {
        //遍历sd卡中crash文件夹,,,得到每一个文件

        //使用okhttp的post方式上传file文件

        //把上传的文件crash文件夹中删除

    }

    /**
     * 自己处理异常的方法
     * @return
     * @param throwable
     */
    private boolean handlerException(Throwable throwable) {
        if (throwable == null){
            return false;
        }
        //吐司提示一下
        new Thread(){
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(context,"程序异常",Toast.LENGTH_SHORT).show();
                Looper.loop();
            }
        }.start();

        //日志写到文件中去
        if (! logDir.exists()){
            logDir.mkdirs();
        }

        //文件夹中创建文件...crash-2017-12-07-HH-mm-ss-SSS.log
        File logFile = new File(logDir,"crash-"+dateFormat.format(new Date())+"-.log");
        if (!logFile.exists()){
            try {
                logFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //写入sd卡...使用打印流
        try {
            PrintWriter printWriter = new PrintWriter(logFile);

            collectLogInfoToSdCard(printWriter,throwable);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


        return true;
    }

    /**
     * 写入sd卡
     * @param printWriter
     * @param throwable
     */
    private void collectLogInfoToSdCard(PrintWriter printWriter, Throwable throwable) {
        //日志里面可能会哟版本号 版本名称 时间

        //获取pakage管理者对象
        PackageManager packageManager = context.getPackageManager();
        //获取当前应用的信息....(context.getPackageName()获取当前应用的包名
        try {
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);

            printWriter.print("版本:");
            printWriter.println(packageInfo.versionCode);
            printWriter.print("版本名称:");
            printWriter.println(packageInfo.versionName);

            printWriter.print("time");
            printWriter.println(dateFormat.format(new Date()));

            //把日志信息放到打印流中去打印
            throwable.printStackTrace(printWriter);

            printWriter.close();

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

    }
}

util包
ImagePipelineConfigUtils.java
package com.example.dasd.yuekao1.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;

import com.facebook.cache.disk.DiskCacheConfig;
import com.facebook.common.disk.NoOpDiskTrimmableRegistry;
import com.facebook.common.internal.Supplier;
import com.facebook.common.memory.MemoryTrimType;
import com.facebook.common.memory.MemoryTrimmable;
import com.facebook.common.memory.NoOpMemoryTrimmableRegistry;
import com.facebook.common.util.ByteConstants;
import com.facebook.imagepipeline.cache.MemoryCacheParams;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.core.ImagePipelineFactory;

/**
 * Created by yujie on 2018/1/18.
 */

public class ImagePipelineConfigUtils {
    //分配的可用内存
    private static final int MAX_HEAP_SIZE = (int) Runtime.getRuntime().maxMemory();
    //使用的缓存数量
    private static final int MAX_MEMORY_CACHE_SIZE = MAX_HEAP_SIZE / 4;
    //小图极低磁盘空间缓存的最大值(特性:可将大量的小图放到额外放在另一个磁盘空间防止大图占用磁盘空间而删除了大量的小图)
    private static final int MAX_SMALL_DISK_VERYLOW_CACHE_SIZE = 20 * ByteConstants.MB;
    //小图低磁盘空间缓存的最大值(特性:可将大量的小图放到额外放在另一个磁盘空间防止大图占用磁盘空间而删除了大量的小图)
    private static final int MAX_SMALL_DISK_LOW_CACHE_SIZE = 60 * ByteConstants.MB;
    //默认图极低磁盘空间缓存的最大值
    private static final int MAX_DISK_CACHE_VERYLOW_SIZE = 20 * ByteConstants.MB;
    //默认图低磁盘空间缓存的最大值
    private static final int MAX_DISK_CACHE_LOW_SIZE = 60 * ByteConstants.MB;
    //默认图磁盘缓存的最大值
    private static final int MAX_DISK_CACHE_SIZE = 100 * ByteConstants.MB;
    //小图所放路径的文件夹名
    private static final String IMAGE_PIPELINE_SMALL_CACHE_DIR = "ImagePipelineCacheSmall";
    //默认图所放路径的文件夹名
    private static final String IMAGE_PIPELINE_CACHE_DIR = "ImagePipelineCacheDefault";
    public static ImagePipelineConfig getDefaultImagePipelineConfig(Context context) {
        //内存配置
        final MemoryCacheParams bitmapCacheParams = new MemoryCacheParams(
                MAX_MEMORY_CACHE_SIZE,// 内存缓存中总图片的最大大小,以字节为单位。
                Integer.MAX_VALUE,// 内存缓存中图片的最大数量。
                MAX_MEMORY_CACHE_SIZE,// 内存缓存中准备清除但尚未被删除的总图片的最大大小,以字节为单位。
                Integer.MAX_VALUE,// 内存缓存中准备清除的总图片的最大数量。
                Integer.MAX_VALUE);// 内存缓存中单个图片的最大大小。
        //修改内存图片缓存数量,空间策略(这个方式有点恶心)
        Supplier<MemoryCacheParams> mSupplierMemoryCacheParams = new Supplier<MemoryCacheParams>() {
            @Override
            public MemoryCacheParams get() {
                return bitmapCacheParams;
            }
        };
        //小图片的磁盘配置
        DiskCacheConfig diskSmallCacheConfig = DiskCacheConfig.newBuilder(context).setBaseDirectoryPath(context.getApplicationContext().getCacheDir())//缓存图片基路径
                .setBaseDirectoryName(IMAGE_PIPELINE_SMALL_CACHE_DIR)//文件夹名
                .setMaxCacheSize(MAX_DISK_CACHE_SIZE)//默认缓存的最大大小。
                .setMaxCacheSizeOnLowDiskSpace(MAX_SMALL_DISK_LOW_CACHE_SIZE)//缓存的最大大小,使用设备时低磁盘空间。
                .setMaxCacheSizeOnVeryLowDiskSpace(MAX_SMALL_DISK_VERYLOW_CACHE_SIZE)//缓存的最大大小,当设备极低磁盘空间
                .setDiskTrimmableRegistry(NoOpDiskTrimmableRegistry.getInstance())
                .build();
        //默认图片的磁盘配置
        DiskCacheConfig diskCacheConfig = DiskCacheConfig.newBuilder(context).setBaseDirectoryPath(Environment.getExternalStorageDirectory().getAbsoluteFile())//缓存图片基路径
                .setBaseDirectoryName(IMAGE_PIPELINE_CACHE_DIR)//文件夹名
                .setMaxCacheSize(MAX_DISK_CACHE_SIZE)//默认缓存的最大大小。
                .setMaxCacheSizeOnLowDiskSpace(MAX_DISK_CACHE_LOW_SIZE)//缓存的最大大小,使用设备时低磁盘空间。
                .setMaxCacheSizeOnVeryLowDiskSpace(MAX_DISK_CACHE_VERYLOW_SIZE)//缓存的最大大小,当设备极低磁盘空间
                .setDiskTrimmableRegistry(NoOpDiskTrimmableRegistry.getInstance())
                .build();
        //缓存图片配置
        ImagePipelineConfig.Builder configBuilder = ImagePipelineConfig.newBuilder(context)
                .setBitmapsConfig(Bitmap.Config.RGB_565)
                .setBitmapMemoryCacheParamsSupplier(mSupplierMemoryCacheParams)
                .setSmallImageDiskCacheConfig(diskSmallCacheConfig)
                .setMainDiskCacheConfig(diskCacheConfig)
                .setMemoryTrimmableRegistry(NoOpMemoryTrimmableRegistry.getInstance())
                .setResizeAndRotateEnabledForNetwork(true);
        // 就是这段代码,用于清理缓存
        NoOpMemoryTrimmableRegistry.getInstance().registerMemoryTrimmable(new MemoryTrimmable() {
            @Override
            public void trim(MemoryTrimType trimType) {
                final double suggestedTrimRatio = trimType.getSuggestedTrimRatio();
                Log.d("", String.format("onCreate suggestedTrimRatio : %d", suggestedTrimRatio));
                if (MemoryTrimType.OnCloseToDalvikHeapLimit.getSuggestedTrimRatio() == suggestedTrimRatio
                        || MemoryTrimType.OnSystemLowMemoryWhileAppInBackground.getSuggestedTrimRatio() == suggestedTrimRatio
                        || MemoryTrimType.OnSystemLowMemoryWhileAppInForeground.getSuggestedTrimRatio() == suggestedTrimRatio
                        ) {
                    ImagePipelineFactory.getInstance().getImagePipeline().clearMemoryCaches();
                }
            }
        });
        return configBuilder.build();
    }
}


util包
RetrofitHelper.java
package com.example.dasd.yuekao1.util;

import android.os.Environment;

import java.io.File;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Created by yujie on 2018/1/18.
 */

public class RetrofitHelper {
    public static OkHttpClient okHttpClient;
    public static ApiService apiService;

    static {
        getOkHttpClient();
    }

    public static OkHttpClient getOkHttpClient(){
        if(okHttpClient == null){
            synchronized (OkHttpClient.class) {
                if(okHttpClient == null){
                    File fileDir = new File(Environment.getExternalStorageDirectory(), "cache");
                    long fileSize = 10 * 1024 * 1024;
                    okHttpClient = new OkHttpClient.Builder()
                            .connectTimeout(15, TimeUnit.SECONDS)
                            .readTimeout(15, TimeUnit.SECONDS)
                            .writeTimeout(15, TimeUnit.SECONDS)
                            .cache(new Cache(fileDir, fileSize))
                            .build();
                }
            }
        }
        return okHttpClient;
    }

    public static ApiService getApiService(String baseUrl){
        if(apiService == null){
            synchronized (OkHttpClient.class) {
                apiService = createApiService(baseUrl, ApiService.class);
            }
        }
        return apiService;
    }

    private static <T>T createApiService(String baseUrl, Class<T> tClass) {
        T t = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build()
                .create(tClass);
        return t;
    }

}








  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值