自定义饼图与listview联动

项目效果图:


                                        


联动效果:见米多财富大众app账户管家模块


源码:

package com.miduo.financialmanageclient.widget;

import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.ListView;

import com.miduo.financialmanageclient.R;
import com.miduo.financialmanageclient.bean.AccountAsset;
import com.miduo.financialmanageclient.bean.MyPoint;
import com.miduo.financialmanageclient.bean.RotateBean;

/**
 * 
 * @author huozhenpeng
 * 
 */
public class RotationView extends ImageView {
	private int width;
	private int height;
	private Paint paint;
	private Paint virtualPaint;
	private RectF rectf;
	private int paintWidth;
	private int margin;
	private double startAngle;// 记录开始角度
	private Matrix matrix;
	private double totalRotation;
	private double tempRotation;
	private int padding;// 设置padding或者leftpadding
	private boolean isFirst = true;
	private Bitmap imageScaled;
	private Canvas mCanvas;
	private TextPaint textpaint;
	private int textsize = 50;
	private FontMetrics fontMetrics;
	private List<AccountAsset> datas;
	private AccountAsset accountAsset;
	public  int currentIndex = 0;
	private Context context;

	public RotationView(Context context) {
		this(context, null);
	}

	public RotationView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public RotationView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.context=context;
		init();
	}

	public void init() {
		this.setScaleType(ScaleType.MATRIX);
		paintWidth=(int) context.getResources().getDimension(R.dimen.px2dp_100);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		paint.setStrokeWidth(paintWidth);
		paint.setStyle(Style.STROKE);
		
		virtualPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		virtualPaint.setStrokeWidth(paintWidth);
		virtualPaint.setStyle(Style.FILL);
		textpaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		textpaint.setTextSize(textsize);
		textpaint.setTextAlign(Align.CENTER);
		if (matrix == null) {
			matrix = new Matrix();
		} else {
			matrix.reset();
		}
		setImageMatrix(matrix);
		
		
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//		super.onMeasure(heightMeasureSpec, heightMeasureSpec);//6.0系统不起作用,所以宽度也写死
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		width = w;
		height = h;
		padding = getPaddingLeft();
		margin = padding + paintWidth / 2;
		rectf = new RectF(margin, margin, width - margin, height - margin);
		imageScaled = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		mCanvas = new Canvas();
		mCanvas.setBitmap(imageScaled);
		fontMetrics = textpaint.getFontMetrics();

	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
//		if (datas != null) {
//			textpaint.setColor(Color.parseColor(datas.get(currentIndex)
//					.getColor()));
//			canvas.drawText(
//					datas.get(currentIndex).getShowData(),
//					width / 2,
//					height / 2 - (fontMetrics.ascent + fontMetrics.descent) / 2,
//					textpaint);
//		}

	}

	/**
	 * 得到(x,y)点的象限值
	 * 
	 * @return quadrant 1,2,3 or 4
	 */
	private static int getQuadrant(double x, double y) {
		if (x >= 0) {
			return y >= 0 ? 1 : 4;
		} else {
			return y >= 0 ? 2 : 3;
		}
	}

	/**
	 * 得到(x,y)点的角度
	 */
	private double getAngle(double x, double y) {
		x = x - (width / 2d);
		y = height - y - (height / 2d);// (就是wheelHeight/2-y,由于变为数学中的坐标系,所以相当于取了一下反)

		switch (getQuadrant(x, y)) {
		case 1:
			return Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
		case 2:
			return 180 - Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
		case 3:
			return 180 + (-1 * Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI);
		case 4:
			return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
		default:
			return 0;
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			startAngle = parseFormat(getAngle(event.getX(), event.getY()));
			break;

		case MotionEvent.ACTION_MOVE:
			if(datas!=null&&datas.size()>1)
			{
				double currentAngle = parseFormat(getAngle(event.getX(), event.getY()));
				double deltaDegrees=startAngle - currentAngle;
				totalRotation=totalRotation%360;
				//1. 控制角度旋转
				if(totalRotation<0)
				{
					totalRotation = 360 + tempRotation;
				}
				tempRotation=(totalRotation+deltaDegrees)%360;
				if (tempRotation < 0) {
					tempRotation = 360 + tempRotation;
				}
				if(datas.get(0).getPoint().getX3()<=tempRotation&&tempRotation<=(int)datas.get(1).getPoint().getX3())
				{
					rotateWheel((float) (startAngle - currentAngle));

				}
				else if(tempRotation>datas.get(1).getPoint().getX3())
				{
					rotateWheel((float)((datas.get(1).getPoint().getX3())-totalRotation));
				}
				//2.   360度旋转
//				rotateWheel((float) (startAngle - currentAngle));
				startAngle = currentAngle;

			}
			break;

		case MotionEvent.ACTION_UP:
			totalRotation = totalRotation % 360;
			if (totalRotation < 0) {
				totalRotation = 360 + totalRotation;
			}
			MyPoint point = null;
			for (int i = 0; i < datas.size(); i++) {
				point = datas.get(i).getPoint();
				if (point.getX1() < totalRotation
						&& totalRotation < point.getX2()) {
					rotateWheel((float) (point.getX3() - totalRotation));
					currentIndex = i;
				}

			}

			break;
		}

		return true;
		
	}

	/**
	 * 要旋转的角度,滑动扇形旋转
	 * 
	 * @param degrees
	 */
	public void rotateWheel(float degrees) {
		matrix.postRotate(degrees, width / 2, height / 2);
		setImageMatrix(matrix);
		totalRotation = parseFormat(totalRotation + degrees);
		//让listview联动
		if(onListViewMoveListener!=null)
		{
			double tempTotalRotation = totalRotation % 360;
			if (tempTotalRotation < 0) {
				tempTotalRotation = 360 + tempTotalRotation;
			}
			onListViewMoveListener.onMove(tempTotalRotation);
		}
		
	}
	/**
	 * 要旋转的角度,滑动listview调用
	 * 
	 * @param degrees
	 */
	public void rotateWheel3(float degrees) {
		matrix.postRotate(degrees, width / 2, height / 2);
		setImageMatrix(matrix);
		totalRotation = totalRotation + degrees;
	}
	
	
	
	/**
	 * 要旋转的角度
	 * 
	 * @param degrees
	 */
	public void rotateWheel2(float degrees) {
		matrix.postRotate(degrees, width / 2, height / 2);
		setImageMatrix(matrix);
	}

	/**
	 * 设置数据,寻找规律
	 * 
	 * degree x1 x2 x3
	 * 
	 * 0 90 0 90 45
	 * 
	 * 1 60 300 360 330
	 * 
	 * 2 50 250 300 275
	 * 
	 * 3 160 90 250 170
	 * 
	 * 
	 * @param datas
	 */
	public void setData(List<AccountAsset> datas) {
		this.datas = datas;
		// 为point属性赋值
		for (int i = 0; i < datas.size(); i++) {
			MyPoint point = new MyPoint();
			double x1 = 0;
			double x2 = 0;
			double x3 = 0;
			if (i == 0) {
				x1 = 0;
				x2 = datas.get(i).getDegrees();
				x3 = parseFormat(x2 / 2.0);
				point.set(x1, x2, x3);
			} else {
				for (int j = i + 1; j < datas.size(); j++) {
					x1 += datas.get(j).getDegrees();
				}
				x3 = parseFormat(x1 + datas.get(i).getDegrees() / 2.0
						+ datas.get(0).getDegrees());
				x1 += datas.get(0).getDegrees();
				x2 = x1 + datas.get(i).getDegrees();
				point.set(x1, x2, x3);
			}
			datas.get(i).setPoint(point);
		}


		init();
		if (isFirst) {
			if (datas != null) {
				int sumDegrees = 0;
				for (int i = 0; i < datas.size(); i++) {
					accountAsset = datas.get(i);
					paint.setColor(Color.parseColor(accountAsset.getColor()));
					virtualPaint.setColor(Color.parseColor(accountAsset.getVirtualColor()));
					mCanvas.drawArc(rectf, sumDegrees, accountAsset.getDegrees(),
							false, paint);
					mCanvas.drawArc(rectf, sumDegrees, accountAsset.getDegrees(),
							true, virtualPaint);

					sumDegrees += accountAsset.getDegrees();
				}
			}
		}
		isFirst = false;
		setImageBitmap(imageScaled);
		if (datas != null) {
			rotateWheel2((float)parseFormat(90-datas.get(0).getDegrees()/2));//初始旋转,让第一个元素位于底部
		}
		totalRotation=parseFormat(datas.get(0).getDegrees()/2);
	}
	public int getTotalDegrees()
	{
		return (int) totalRotation;
	}
	
	private OnListViewMoveListener onListViewMoveListener;
	public interface OnListViewMoveListener
	{
		void onMove(double degrees);
	}
	/**
	 * 控制listview联动
	 */
	public void setListViewMoveListener(OnListViewMoveListener onListViewMoveListener)
	{
		this.onListViewMoveListener=onListViewMoveListener;
	}
	
	private ListView listview;
	public void setListView(ListView listview)
	{
		this.listview=listview;
	}
	
	public double getTotalRotation()
	{
		double tempTotalRotation = totalRotation % 360;
		if (tempTotalRotation < 0) {
			tempTotalRotation = 360 + tempTotalRotation;
		}
		return tempTotalRotation;
	}

	public double parseFormat(double value)
	{
		return Double.parseDouble(String.format("%.1f", value));
	}

}



package com.miduo.financialmanageclient.bean;

import java.io.Serializable;

public class MyPoint implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public MyPoint() {
		// TODO Auto-generated constructor stub
	}

	private double x1;
	private double x2;
	private double x3;

	public double getX1() {
		return x1;
	}

	public void setX1(double x1) {
		this.x1 = x1;
	}

	public double getX2() {
		return x2;
	}

	public void setX2(double x2) {
		this.x2 = x2;
	}

	public double getX3() {
		return x3;
	}

	public void setX3(double x3) {
		this.x3 = x3;
	}

	public void set(double x1, double x2, double x3)
	{
		this.x1=x1;
		this.x2=x2;
		this.x3=x3;
	}

	@Override
	public String toString() {
		return "MyPoint [x1=" + x1 + ", x2=" + x2 + ", x3=" + x3 + "]";
	}
	
	

}


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

    <RelativeLayout
        android:id="@+id/top_layout"
        android:layout_width="match_parent"
        android:layout_height="@dimen/px2dp_96"
        android:background="#517eb0" >

        <ImageView
            android:id="@+id/left_img"
            android:layout_width="@dimen/px2dp_77"
            android:layout_height="match_parent"
            android:layout_centerVertical="true"
            android:contentDescription="@string/app_name"
            android:scaleType="center"
            android:src="@mipmap/head_arrow" />


        <TextView
            android:id="@+id/title_txt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="资产配置分析"
            android:textColor="#ffffff"
            android:textSize="@dimen/px2sp_34" />
    </RelativeLayout>

    <LinearLayout
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="@dimen/px2dp_60"
        android:layout_width="@dimen/px2dp_400"
        android:layout_height="@dimen/px2dp_400"
        android:orientation="horizontal" >


        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="@dimen/px2dp_400">
            <com.miduo.financialmanageclient.widget.RotationView
                android:id="@+id/rotateView"
                android:layout_width="@dimen/px2dp_400"
                android:layout_height="@dimen/px2dp_400" />
            <com.miduo.financialmanageclient.widget.TextView
                android:gravity="center_horizontal"
                android:layout_width="@dimen/px2dp_300"
                android:layout_height="wrap_content"
                android:text="@string/default_value"
                android:textSize="@dimen/px2sp_42"
                android:textColor="#333333"
                android:layout_centerInParent="true"
                android:id="@+id/tv_money"
                special:typeface="true"

                />
            <LinearLayout
                android:layout_width="@dimen/px2dp_300"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_centerHorizontal="true"
                android:layout_below="@id/tv_money"
                >
                <TextView
                    android:gravity="center_horizontal"
                    android:id="@+id/tv_amounttips"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="总资产"
                    android:textColor="#333333"
                    android:textSize="@dimen/px2sp_24"
                    />
            </LinearLayout>


        </RelativeLayout>




    </LinearLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <com.miduo.financialmanageclient.widget.ArrowView
            android:id="@+id/arrowView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        <ListView
            android:layout_marginTop="@dimen/px2dp_56"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@null"
            android:id="@+id/listview"
            ></ListView>

    </FrameLayout>

</LinearLayout>


package com.miduo.financialmanageclient.ui;

import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.google.gson.reflect.TypeToken;
import com.miduo.financialmanageclient.R;
import com.miduo.financialmanageclient.bean.AccountAsset;
import com.miduo.financialmanageclient.bean.MyPoint;
import com.miduo.financialmanageclient.ui.adapter.ScrollAdapter;
import com.miduo.financialmanageclient.util.FloatUtil;
import com.miduo.financialmanageclient.util.JsonUtils;
import com.miduo.financialmanageclient.util.ProgressDialogUtil;
import com.miduo.financialmanageclient.util.ThreadManager;
import com.miduo.financialmanageclient.widget.ArrowView;
import com.miduo.financialmanageclient.widget.RotationView;
import com.miduo.financialmanageclient.ws.AppException;
import com.miduo.financialmanageclient.ws.WebServiceClient;

import org.json.JSONObject;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author huozhenpeng
 *         资产配置分析
 */
public class AccountStewardActivity extends BaseActivity implements OnClickListener {
    private List<AccountAsset> lists;
    private RotationView rotationView;
    private ArrowView arrowView;
    private ListView listview;
    private ScrollAdapter scrollAdapter;
    private int position;
    private int top;
    private int itemHeight;
    // 静止之后实际的position
    private int actualPosition;
    private MyRunnable myRunnable = new MyRunnable();
    private List<AccountAsset> tempLists = new ArrayList<>();
    private boolean isListMove = true;
    private boolean isInit = true;
    private TextView tv_money;
    private MyHandler handler;
    private ImageView left_img;
    private TextView tv_amounttips;

    @Override
    public void onClick(View view) {

        switch (view.getId())
        {
            case R.id.left_img:
                finish();
                break;
        }

    }

    @Override
    protected void initVariables() {
        titleInfo = "资产配置分析";

    }

    @Override
    protected void initViews() {
        setContentView(R.layout.activity_accountsteward);
        tv_amounttips= (TextView) this.findViewById(R.id.tv_amounttips);
        left_img= (ImageView) this.findViewById(R.id.left_img);
        tv_money = (TextView) this.findViewById(R.id.tv_money);
        rotationView = (RotationView) this.findViewById(R.id.rotateView);
        arrowView = (ArrowView) this.findViewById(R.id.arrowView);
        map = new HashMap<>();
        handler = new MyHandler(this);
        lists = new ArrayList<>();
        listview = (ListView) this.findViewById(R.id.listview);
        scrollAdapter = new ScrollAdapter(this, lists);
        listview.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        if (isInit) {
                            isInit = false;
                            int[] position = new int[2];
                            listview.getLocationOnScreen(position);

                            Display display = getWindowManager()
                                    .getDefaultDisplay();// 得到当前屏幕的显示器对象
                            Point size = new Point();// 创建一个Point点对象用来接收屏幕尺寸信息
                            display.getSize(size);// Point点对象接收当前设备屏幕尺寸信息
                            int width = size.x;// 从Point点对象中获取屏幕的宽度(单位像素)
                            int vHeight = size.y;// 从Point点对象中获取屏幕的高度(单位像素)

                            // 获取每个item的高度
                            View itemView = LayoutInflater.from(
                                    AccountStewardActivity.this).inflate(
                                    R.layout.item_scroll, null);
                            View view = new View(AccountStewardActivity.this);
                            itemHeight = measure_ll_transfer1Height(itemView);
                            AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(
                                    ViewGroup.LayoutParams.MATCH_PARENT, vHeight
                                    - position[1] - itemHeight);
                            view.setLayoutParams(layoutParams);
                            listview.addFooterView(view);
                            listview.setAdapter(scrollAdapter);

                            FrameLayout.LayoutParams layoutParams1 = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (itemHeight * 4 / 3.0f));
                            arrowView.setLayoutParams(layoutParams1);
                            arrowView.invalidate();

                        }
                    }
                });
        listview.setOnScrollListener(new AbsListView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                switch (scrollState) {
                    case SCROLL_STATE_FLING:// 手指离开屏幕后,惯性滑动

                        break;
                    case SCROLL_STATE_IDLE:// 滑动后静止
                        if (isListMove) {
                            position = listview.getFirstVisiblePosition();// 第几个item
                            top = getViewByPosition(position, listview).getTop();
                            if (-top <= itemHeight / 2) {
                                myRunnable.setPosition(position);
                                actualPosition = position;
                            } else {
                                myRunnable.setPosition(position + 1);
                                actualPosition = position + 1;
                            }
                            myRunnable.setOffset(0);
                            listview.post(myRunnable);
                        }


                        break;
                    case SCROLL_STATE_TOUCH_SCROLL:// 手指在屏幕上滑动
                        break;

                    default:
                        break;
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                                 int visibleItemCount, int totalItemCount) {
                //启动时getScrollY为0
                if (isListMove) {
                    callbackPie1(getScrollY());
                } else {
                    oldDistance = getScrollY();
                }
                changeColor(getScrollY());

            }
        });

        listview.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                isListMove = true;
                return false;
            }
        });
        rotationView.setListViewMoveListener(new RotationView.OnListViewMoveListener() {

            @Override
            public void onMove(double degrees) {
                isListMove = false;
                lists.get(0);
                int index = -1;
                double offest = 0;
                for (int i = 0; i < lists.size() - 1; i++) {
                    MyPoint point1 = lists.get(i).getPoint();
                    MyPoint point2 = lists.get(i + 1).getPoint();
                    if (point1.getX3() <= degrees && degrees <= point1.getX2()) {
                        offest = itemHeight / 2.0f * (degrees - point1.getX3()) / (point1.getX2() - point1.getX3());
                        index = i;
                        break;
                    } else if (point1.getX2() <= degrees && degrees <= point2.getX3()) {
                        offest = itemHeight / 2.0f + itemHeight / 2.0f * (degrees - point1.getX2()) / (point2.getX3() - point1.getX2());
                        index = i;
                        break;
                    }
                }
                if(degrees==0)
                {
                    index = lists.size()-1;
                    offest = 0;
                }
                //index变化的时候会闪屏
//				listview.smoothScrollToPositionFromTop(index, -(int)offest, 0);
                //不会回调onScroll方法
//				listview.scrollTo(0, index*itemHeight+(int)offest);
                listview.setSelectionFromTop(index, -(int) offest);

            }
        });

    }

    @Override
    protected void initEvents() {
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if(i<lists.size()) {
                    Intent intent = new Intent(AccountStewardActivity.this, FinancialProductsListActivity.class);
                    intent.putExtra("assetType", lists.get(i).getAssetType());
                    intent.putExtra("assetName",((TextView)view.findViewById(R.id.tv_type)).getText().toString());
                    startActivity(intent);
                    finish();
                }
            }
        });
        left_img.setOnClickListener(this);
    }

    private Map<String, String> map;

    @Override
    protected void loadData() {
        ProgressDialogUtil.showProgress(this);
        ThreadManager.getLongPool().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    String result = WebServiceClient.getAssetsAnalysis(null);
                    Message message = Message.obtain();
                    message.obj = result;
                    message.what = 0x01;
                    handler.sendMessage(message);

                } catch (AppException e) {
                    e.printStackTrace();
                    handler.sendEmptyMessage(0x02);
                }
            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    private static class MyHandler extends Handler {
        private WeakReference<AccountStewardActivity> _activity;

        public MyHandler(AccountStewardActivity activity) {
            _activity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            AccountStewardActivity activity = _activity.get();
            if (activity == null) {
                return;
            }
            switch (msg.what) {
                case 0x01:
                    ProgressDialogUtil.closeProgress();
                    String result = (String) msg.obj;
                    if (!TextUtils.isEmpty(result)) {
                        JSONObject jo = null;
                        try {
                            jo = new JSONObject(result);
                            int state = jo.getInt("state");
                            String resultMsg = jo.optString("msg");
                            String data = jo.optString("data");
                            if (state == 1) {
                                List<AccountAsset> lists = JsonUtils.toBean(data, new TypeToken<List<AccountAsset>>() {
                                }.getType());
                                if (lists != null && lists.size() > 0) {
                                    for (int i = 0; i < lists.size(); i++) {
                                        lists.get(i).setDegrees((int) (lists.get(i).getPercent()*360));
                                    }
                                    //处理原始数据,percent不为0,但是度数为0的,分配1度,
                                    //所有度数和大于360的从最大中减去,小于360的加给最大值
                                    AccountAsset accountAsset=null;
                                    int Degrees=0;
                                    for(int i=0;i<lists.size();i++)
                                    {
                                        accountAsset=lists.get(i);
                                        if(accountAsset.getPercent()>0&&accountAsset.getDegrees()<1)
                                        {
                                            accountAsset.setDegrees(1);
                                        }
                                    }
                                    for(int i=0;i<lists.size();i++)
                                    {
                                        Degrees+=lists.get(i).getDegrees();
                                    }
                                    lists.get(0).setDegrees(lists.get(0).getDegrees()+(360-Degrees));
                                    for (int i = 0; i < lists.size(); i++) {
                                        if (i == 0) {
                                            activity.tempLists.add(lists.get(0));
                                        } else {
                                            activity.tempLists.add(lists.get(lists.size() - i));
                                        }
                                    }
                                    activity.rotationView.setData(activity.tempLists);
                                    activity.lists.clear();
                                    activity.lists.addAll(lists);
                                    activity.scrollAdapter.notifyDataSetChanged();

                                }
                            }

                        } catch (Exception e) {

                        }
                    }

                    break;
                case 0x02:
                    ProgressDialogUtil.closeProgress();
                    break;
            }
        }
    }

    private float oldDistance;

    /**
     * 让饼图联动,根据listview滑动的距离
     * itemHeight : 147
     * distance   :  147*3=447
     * <p>
     * 问题:每个delta可能跨两个或者多个扇形,快速滑动,回调是不连续的
     */
    private void callbackPie1(float distance) {
        if (itemHeight == 0)
            return;
        if(lists==null||lists.size()==0)
            return;
        float delta = distance - oldDistance;
        float reminder = Math.max(distance, oldDistance) % itemHeight;
        int divider = (int) (Math.max(distance, oldDistance) / itemHeight);

        //判断delta是否跨扇形
        int location = (int) (distance / (itemHeight / 2.0f));
        int oldLocation = (int) (oldDistance / (itemHeight / 2.0f));
        int deltaLocation = location - oldLocation;
        if (deltaLocation > 0 && !(deltaLocation == 0 || Math.abs(deltaLocation) == 1 && distance % (itemHeight / 2.0f) == 0)) {
            for (int i = 1; i <= deltaLocation; i++) {
                callbackPie1((oldLocation + 1) * itemHeight / 2.0f);
            }
            callbackPie1(distance);

        } else if (deltaLocation < 0 && !(deltaLocation == 0 || Math.abs(deltaLocation) == 1 && (Math.max(distance, oldDistance) % (itemHeight / 2.0f) == 0))) {
            oldLocation = oldLocation + 1;
            if (oldDistance % (itemHeight / 2.0f) == 0) {
                deltaLocation += 1;
            }
            for (int i = 1; i <= Math.abs(deltaLocation); i++) {
                if (oldDistance % (itemHeight / 2.0f) == 0) {
                    oldLocation = oldLocation - 1;
                }
                callbackPie1((oldLocation - 1) * itemHeight / 2.0f);
            }
            callbackPie1(distance);
        } else {
            //刚刚开始distance和oldDistance都是0
            if (reminder <= (itemHeight / 2.f)) {
                rotationView.rotateWheel3(lists.get(divider).getDegrees() * 1.0f
                        / 2 / (itemHeight / 2.0f) * delta);
            } else {
                if (divider <= tempLists.size() - 1) {
                    rotationView.rotateWheel3(lists.get(divider + 1).getDegrees() * 1.0f
                            / 2 / (itemHeight / 2.0f) * delta);
                } else {
                    rotationView.rotateWheel3(lists.get(0).getDegrees() * 1.0f
                            / 2 / (itemHeight / 2.0f) * delta);
                }
            }
            oldDistance = distance;
        }

    }

    public View getViewByPosition(int pos, ListView listView) {
        final int firstListItemPosition = listView.getFirstVisiblePosition();
        final int lastListItemPosition = firstListItemPosition
                + listView.getChildCount() - 1;

        if (pos < firstListItemPosition || pos > lastListItemPosition) {
            return listView.getAdapter().getView(pos, null, listView);
        } else {
            final int childIndex = pos - firstListItemPosition;
            return listView.getChildAt(childIndex);
        }
    }

    private int measure_ll_transfer1Height(View view) {
        view.getLayoutParams();
        int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(
                ViewGroup.LayoutParams.MATCH_PARENT, View.MeasureSpec.EXACTLY);
        int heightMeasureSpec = 0;
        if (android.os.Build.VERSION.SDK_INT >= 18) {
            heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
                    ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.AT_MOST);
        } else {
            heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
                    ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.EXACTLY);
        }
        view.measure(widthMeasureSpec, heightMeasureSpec);
        return view.getMeasuredHeight();
    }

    class MyRunnable implements Runnable {

        private int position;
        private int offset;

        public void setPosition(int position) {
            this.position = position;
        }

        public void setOffset(int offset) {
            this.offset = offset;
        }

        @Override
        public void run() {
            listview.smoothScrollToPositionFromTop(position, offset, 500);
        }
    }

    public int getScrollY() {
        View c = listview.getChildAt(0);
        if (c == null) {
            return 0;
        }
        int firstVisiblePosition = listview.getFirstVisiblePosition();
        int top = c.getTop();
        return -top + firstVisiblePosition * c.getHeight();
    }

    private int oldIndex = -1;

    private void changeColor(int distance) {
        if(lists==null||lists.size()==0)
            return;

        if (listview != null && listview.getAdapter() != null) {
            int index = 0;
            if (distance < itemHeight) {
                index = 0;
            } else {
                index = (int) ((distance) / (itemHeight));

            }
            if (index != oldIndex) {
                if(oldIndex>=0) {
                    //percent太小,转动过快,造成index和oldindex不连续
                    int max=Math.max(index,oldIndex);
                    int min=Math.min(index,oldIndex);
                    for(int i=max;i>min;i--)
                    {
                        View view1 = getViewByPosition(i, listview);
                        RelativeLayout relativeLayout = (RelativeLayout) view1.findViewById(R.id.rl_background);
                        relativeLayout.setBackgroundColor(Color.parseColor("#ffffff"));
                        LinearLayout linearLayout = (LinearLayout) view1.findViewById(R.id.ll_parent);
                        View deviderView = linearLayout.findViewById(R.id.v_devider);
                        deviderView.setBackgroundColor(Color.parseColor("#dcdcdc"));
                        arrowView.setVirtualColor("#ffffff");
                    }

                }
                View view = getViewByPosition(index, listview);
                RelativeLayout relativeLayout = (RelativeLayout) view.findViewById(R.id.rl_background);
                relativeLayout.setBackgroundColor(Color.parseColor(lists.get(index).getVirtualColor()));
                LinearLayout linearLayout= (LinearLayout) view.findViewById(R.id.ll_parent);
                View deviderView = linearLayout.findViewById(R.id.v_devider);
                deviderView.setBackgroundColor(Color.parseColor(lists.get(index).getColor()));
                arrowView.setVirtualColor(lists.get(index).getVirtualColor());
                arrowView.setColor(lists.get(index).getColor());

            }

            try
            {
                tv_money.setText(FloatUtil.toTwoDianStringSeparator(lists.get(index).getGroupYesterdayAsset()));
            }
            catch (Exception e)
            {
                tv_money.setText(lists.get(index).getGroupYesterdayAsset() + "");
            }
            tv_amounttips.setText(getProductType(lists.get(index)));
            oldIndex = index;

        }

    }

    private String  getProductType(AccountAsset accountAsset) {
        String name="";
        switch (accountAsset.getAssetType()) {
            case 1://银行存款
                name="银行存款";
                break;
            case 2://p2p
                name="P2P";
                break;
            case 3://宝宝类
                name="宝宝类";
                break;
            case 4://基金
                name="基金";
                break;
            case 5://股票
                name="股票";
                break;
            case 6://银行理财
                name="银行理财";
                break;
            case 7://信托
                name="信托/资管";
                break;
            case 8://自定义资产
                name="其他资产";
                break;
            default:
                name=AccountStewardActivity.this.getResources().getString(R.string.default_value);
                break;
        }
        return name+"(元)";
    }
}



package com.miduo.financialmanageclient.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.miduo.financialmanageclient.R;

public class ArrowView extends View {
	private Paint paint;
	private Paint virtualPaint;
	private int paintWidth = 2;
	private int width;
	private int height;
	private int delta ;
	private String color;
	private String virtualColor;
	private Path path;

	private Context context;
	public ArrowView(Context context) {
		this(context, null);
	}

	public ArrowView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public ArrowView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.context=context;
		init();
	}

	public void init() {
		delta= (int) context.getResources().getDimension(R.dimen.px2dp_20);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		paint.setStrokeWidth(paintWidth);

		virtualPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		virtualPaint.setStyle(Paint.Style.FILL_AND_STROKE);
		path=new Path();

	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		if (TextUtils.isEmpty(color)) {
			paint.setColor(Color.parseColor("#ffffff"));
		} else {
			paint.setColor(Color.parseColor(color));
		}
		if(TextUtils.isEmpty(virtualColor))
		{
			virtualPaint.setColor(Color.parseColor("#ffffff"));
		}
		else
		{
			virtualPaint.setColor(Color.parseColor(virtualColor));
		}
		path.reset();
		path.moveTo(0,height * 1.0f / 4);
		path.lineTo(width * 1.0f / 2 - delta,height * 1.0f / 4);
		path.lineTo( width * 1.0f / 2,height * 1.0f / 6);
		path.lineTo(width * 1.0f / 2 + delta,
				height * 1.0f / 4);
		path.lineTo(width,height * 1.0f / 4);
		path.lineTo(width,height);
		path.lineTo(0,height);
		path.close();
		canvas.drawPath(path,virtualPaint);

		canvas.drawLine(0, height * 1.0f / 4, width * 1.0f / 2 - delta,
				height * 1.0f / 4, paint);
		canvas.drawLine(width * 1.0f / 2 - delta, height * 1.0f / 4,
				width * 1.0f / 2, height * 1.0f / 6, paint);
		canvas.drawLine(width * 1.0f / 2, height * 1.0f / 6, width * 1.0f / 2 + delta,
				height * 1.0f / 4, paint);
		canvas.drawLine(width * 1.0f / 2 + delta, height * 1.0f / 4, width,
				height * 1.0f / 4, paint);
		canvas.drawLine(width, height * 1.0f / 4, width, height, paint);
//		canvas.drawLine(width, height, 0, height, paint);//底边线
		canvas.drawLine(0, height, 0, height * 1.0f / 4, paint);


	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		width = w;
		height = h;
	}

	public void setColor(String color) {
		this.color=color;
		invalidate();

	}

	public void setVirtualColor(String virtualColor) {
		this.virtualColor=virtualColor;
		invalidate();

	}

}



package com.miduo.financialmanageclient.bean;

import java.io.Serializable;

/**
 * Created by ${huozhenpeng} on 16/12/8.
 * Company : www.miduo.com
 */

public class AccountAsset implements Serializable {

    /**
     * groupYesterdayAsset : 3768960
     * groupYesterdayProfit : 0
     * percent : 1
     * assetType : 3
     * 资产类别(1-银行存款,2-P2P,3-宝宝类,4-基金,5-股票,6-银行理财产品,7-信托、资管,8-自定义资产) ,
     *
     * p2p: #fa582c   #fbe8dd
     * 股票: #da403b  #f9e5e4
     * 理财: #875fd7   #ece8fa
     * 信托: #3e9ecc   #e1f1f7
     * 存款: #2baff4   #dff5fb
     * 其他资产: #9bca53    #f0f8e4
     * 基金: #fed119   #fef9de
     * 宝宝: #eca026  #fbf2de
     *
     */

    private double groupYesterdayAsset;
    private double groupYesterdayProfit;
    private double percent;
    private int assetType;
    private MyPoint point;//只是记录两个点(并非x和y)
    private int degrees;


    public int getDegrees() {
        return degrees;
    }

    public void setDegrees(int degrees) {
        this.degrees = degrees;
    }

    public MyPoint getPoint() {
        return point;
    }

    public void setPoint(MyPoint point) {
        this.point = point;
    }

    public double getGroupYesterdayAsset() {
        return groupYesterdayAsset;
    }

    public void setGroupYesterdayAsset(double groupYesterdayAsset) {
        this.groupYesterdayAsset = groupYesterdayAsset;
    }

    public double getGroupYesterdayProfit() {
        return groupYesterdayProfit;
    }

    public void setGroupYesterdayProfit(double groupYesterdayProfit) {
        this.groupYesterdayProfit = groupYesterdayProfit;
    }

    public double getPercent() {
        return percent;
    }

    public void setPercent(double percent) {
        this.percent = percent;
    }

    public int getAssetType() {
        return assetType;
    }

    public void setAssetType(int assetType) {
        this.assetType = assetType;
    }

    public String getColor()
    {
        String color="#efefef";
        switch (assetType)
        {
            case 1://银行存款
                color="#faa97c";
                break;
            case 2://p2p
                color="#957cfb";
                break;
            case 3://宝宝类
                color="#93d28b";
                break;
            case 4://基金
                color="#fdcf00";
                break;
            case 5://股票
                color="#ff82ae";
                break;
            case 6://银行理财
                color="#6aceee";
                break;
            case 7://信托
                color="#60b0f5";
                break;
            case 8://自定义资产
                color="#5ed9a2";
                break;
        }
        return color;

    }
    public String getVirtualColor()
    {
        String color="#efefef";
        switch (assetType)
        {
            case 1:
                color="#fef3ec";
                break;
            case 2:
                color="#efecfe";
                break;
            case 3:
                color="#eef9ee";
                break;
            case 4:
                color="#fff9d8";
                break;
            case 5:
                color="#ffedf3";
                break;
            case 6:
                color="#e8f9fc";
                break;
            case 7:
                color="#e7f4ff";
                break;
            case 8:
                color="#e7faf1";
                break;
        }
        return color;
    }

    @Override
    public String toString() {
        return "AccountAsset{" +
                "groupYesterdayAsset=" + groupYesterdayAsset +
                ", groupYesterdayProfit=" + groupYesterdayProfit +
                ", percent=" + percent +
                ", assetType=" + assetType +
                '}';
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值