项目效果图:
联动效果:见米多财富大众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 +
'}';
}
}