可以左右滑动的柱形图

显示从今天数,总共30天的柱子,刚进入显示今天,可以往左边滑动显示最近30天,柱子有点击效果。

效果图:

可以左右滑动的柱形图_第1张图片




package com.miduo.financialmanageclient.widget;

import com.miduo.financialmanageclient.R;
import com.miduo.financialmanageclient.bean.ScrollBarBean;
import com.miduo.financialmanageclient.bean.ScrollPerBarBean;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;

/**
 * 
 * @author huozhenpeng
 * 
 */
public class ScrollBarPic extends View {
	private int leftPadding;// 柱子的左右边距
	private int barPadding;// 柱子之间的间距
	private int barbottom;// 柱子的底端位置
	private int bartop;// 柱子的顶端位置
	private int perBarWidth;// 每个柱子的宽度
	private int width;// 控件的宽度
	private int height;// 控件的高度
	private int defaultHeight;// 默认高度
	private ScrollBarBean scrollBarBean;
	private Paint barPaint;// 柱状图画笔
	private TextPaint textPaint;
	private OnClickListener listener;
	private TextPaint textPaint1;// 灰色画笔
	private TextPaint textPaint2;// 蓝色画笔
	private FontMetrics metrics1;
	private FontMetrics metrics2;
	private int baseline1;
	private int baseline2;
	private boolean flag;//是否有选中的柱子

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

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

	public ScrollBarPic(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	private void init() {
		leftPadding = (int) getResources().getDimension(R.dimen.px2dp_42);
		barPadding = (int) getResources().getDimension(R.dimen.px2dp_26);
		bartop = (int) getResources().getDimension(R.dimen.px2dp_66);
		barbottom = (int) getResources().getDimension(R.dimen.px2dp_74);
		defaultHeight = (int) getResources().getDimension(R.dimen.px2dp_10);
		barPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		barPaint.setColor(Color.parseColor("#a3d8f1"));
		// barPaint.setStrokeCap(Cap.SQUARE);//自己埋了个大炕
		textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		textPaint.setColor(Color.parseColor("#000000"));
		barPaint.setStrokeWidth(perBarWidth);
		textPaint1 = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		textPaint1.setTextSize(getResources().getDimension(R.dimen.px2sp_18));
		textPaint1.setColor(Color.parseColor("#999999"));
		textPaint1.setTextAlign(Align.CENTER);
		textPaint2 = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
		textPaint2.setTextSize(getResources().getDimension(R.dimen.px2dp_22));
		textPaint2.setColor(Color.parseColor("#2ea7e0"));
		textPaint2.setTextAlign(Align.CENTER);
		metrics1 = textPaint1.getFontMetrics();
		metrics2 = textPaint2.getFontMetrics();
		baseline1 = (int) ((-metrics1.ascent - metrics1.descent) / 2);
		baseline2 = (int) ((-metrics2.ascent - metrics2.descent) / 2);
		invalidate();

	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		DisplayMetrics dm = getResources().getDisplayMetrics();
		int w_screen = dm.widthPixels;
		perBarWidth = (w_screen - 2 * leftPadding - 7 * barPadding) / 7;
		int width = (perBarWidth + barPadding) * 30;// this的宽度
		setMeasuredDimension(
				MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
				heightMeasureSpec);
	}

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

	@Override
	protected void onDraw(Canvas canvas) {
		if (scrollBarBean == null)
			return;
		canvas.drawColor(Color.parseColor("#ffffff"));
		ScrollPerBarBean perBarBean = null;
		for (int i = 0; i < scrollBarBean.getLists().size(); i++) {
			perBarBean = scrollBarBean.getLists().get(i);

			if (perBarBean.isFlag())// 选中状态
			{
				barPaint.setColor(Color.parseColor("#2ea7e0"));
				// 绘制收益
				canvas.drawText(
						perBarBean.getMoney(),
						barPadding / 2 + perBarWidth / 2
								+ (barPadding + perBarWidth) * i,
						height - barbottom
								+ getResources().getDimension(R.dimen.px2dp_20)
								+ baseline2 + defaultHeight, textPaint2);
				textPaint1.setColor(Color.parseColor("#2ea7e0"));

			} else {
				barPaint.setColor(Color.parseColor("#a3d8f1"));
				textPaint1.setColor(Color.parseColor("#999999"));
			}
			// 先绘制预留高度
			canvas.drawLine(barPadding / 2 + perBarWidth / 2
					+ (barPadding + perBarWidth) * i, height - barbottom,
					barPadding / 2 + perBarWidth / 2
							+ (barPadding + perBarWidth) * i, height
							- barbottom - defaultHeight, barPaint);
			// 绘制柱状图
			canvas.drawLine(barPadding / 2 + perBarWidth / 2
					+ (barPadding + perBarWidth) * i, height - barbottom
					- defaultHeight, barPadding / 2 + perBarWidth / 2
					+ (barPadding + perBarWidth) * i, height - barbottom
					- perBarBean.getActualHeight() - defaultHeight, barPaint);

			// 绘制日期
			canvas.drawText(perBarBean.getDate(), barPadding / 2 + perBarWidth
					/ 2 + (barPadding + perBarWidth) * i, height - barbottom
					- perBarBean.getActualHeight() - baseline1 - defaultHeight,
					textPaint1);

			// 设置左边界
			perBarBean.setLeftX(barPadding / 2 + perBarWidth / 2
					+ (barPadding + perBarWidth) * i - perBarWidth / 2);
			// 设置右边界
			perBarBean.setRightX(barPadding / 2 + perBarWidth / 2
					+ (barPadding + perBarWidth) * i + perBarWidth / 2);
			// 设置上边界
			perBarBean.setTopY(height - perBarBean.getActualHeight()
					- barbottom - defaultHeight);

		}
		super.onDraw(canvas);
	}

	/**
	 * 得到柱子之间的宽度(父容器使用)
	 * 
	 * @return
	 */
	public int getPadding() {
		return barPadding;
	}

	/**
	 * 得到每个柱子的宽度(父容器使用)
	 * 
	 * @return
	 */
	public int getPerbarWidth() {
		return perBarWidth;
	}

	public void setDatas(ScrollBarBean scrollBarBean) {
		this.scrollBarBean = scrollBarBean;
		ScrollPerBarBean perBarBean = null;
		for (int i = 0; i < scrollBarBean.getLists().size(); i++) {
			perBarBean = scrollBarBean.getLists().get(i);
			perBarBean.setActualHeight(perBarBean.getRatio()
					* (height - barbottom - bartop - defaultHeight)
					/ scrollBarBean.getTotal());
//			if (i == scrollBarBean.getLists().size() - 1) {
//				perBarBean.setFlag(true);
//			}
			if(perBarBean.isFlag())
			{
				flag=true;
			}
		}
		if(!flag)
		{
			perBarBean.setFlag(true);
		}
		init();
	}

	int x = 0;
	int y = 0;

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			x = (int) event.getX();
			y = (int) event.getY();
			break;

		default:
			break;
		}
		return super.onTouchEvent(event);
	}

	public void setOnClickListener(OnClickListener listener) {
		this.listener = listener;
	}

	public interface OnClickListener {
		void onclick(int i);
	}

	public void clickcallback(boolean flag) {
		if (!flag) {
			ScrollPerBarBean perBarBean = null;
			for (int i = 0; i < scrollBarBean.getLists().size(); i++) {
				perBarBean = scrollBarBean.getLists().get(i);
				if (perBarBean.getLeftX() < x && x < perBarBean.getRightX()
						&& y > perBarBean.getTopY() && y < height) {
					perBarBean.setFlag(true);
					for (int j = 0; j < scrollBarBean.getLists().size(); j++) {
						if (i != j) {
							scrollBarBean.getLists().get(j).setFlag(false);
						}
					}
					if (listener != null) {
						listener.onclick(i);
					}
					invalidate();
				}
			}
		}
	}

}



package com.miduo.financialmanageclient.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
/**
 * 
 * @author huozhenpeng
 *
 */
public class ScrollViewDragHelper extends LinearLayout {

	private ViewDragHelper viewDragHelper;
	private ScrollBarPic scrollBarPic;
	private int width;// 子孩子的宽度
	private int height;
	private int perBarWidth;// 每个柱子的宽度
	private int padding;// 柱子之间的间隔
	private int initialposition;// 初始位置
	private int leftpadding;// 父容器的padding值(左右padding值应该相等)
	private boolean flag = false;
	private int index;// 记录回退位置

	@SuppressLint("NewApi")
	public ScrollViewDragHelper(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

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

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

	private void init() {
		viewDragHelper = ViewDragHelper.create(this, 1.0f,
				new ViewDragHelper.Callback() {
					@Override
					public boolean tryCaptureView(View child, int pointerId) {
						return true;
					}

					@Override
					public int clampViewPositionHorizontal(View child,
							int left, int dx) {
						if (left > leftpadding) {
							left = leftpadding;
						} else if (left < -initialposition + leftpadding) {
							left = -initialposition + leftpadding;
						}
						if (Math.abs(dx) > 2) {// 记录是否应该回调柱子的点击事件
							flag = true;
						}
						return left;
					}

					@Override
					public void onViewPositionChanged(View changedView,
							int left, int top, int dx, int dy) {
						super.onViewPositionChanged(changedView, left, top, dx,
								dy);
					}

					@Override
					public void onViewReleased(View releasedChild, float xvel,
							float yvel) {
						super.onViewReleased(releasedChild, xvel, yvel);
						if (Math.abs(scrollBarPic.getLeft()) < (perBarWidth + padding) / 2) {
							// 0号
							index = 0;
						} else {
							// 其余的
							index = Math.abs((scrollBarPic.getLeft() - (perBarWidth + padding) / 2)
									/ (perBarWidth + padding));
						}
						if (viewDragHelper.smoothSlideViewTo(scrollBarPic,
								-index * (perBarWidth + padding) + leftpadding,
								0)) {
							// 返回true, 说明还没有移动到指定位置。需要重绘界面
							ViewCompat
									.postInvalidateOnAnimation(ScrollViewDragHelper.this);
						}
					}

				});

	}

	@Override
	public void computeScroll() {
		super.computeScroll();
		if (viewDragHelper.continueSettling(true)) {
			ViewCompat.postInvalidateOnAnimation(this);
		}
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		return viewDragHelper.shouldInterceptTouchEvent(ev);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			flag = false;
			break;
		case MotionEvent.ACTION_MOVE:
			break;
		case MotionEvent.ACTION_UP:
			scrollBarPic.clickcallback(flag);
			break;

		default:
			break;
		}
		viewDragHelper.processTouchEvent(event);
		return true;
	}

	@Override
	protected void onFinishInflate() {
		scrollBarPic = (ScrollBarPic) getChildAt(0);
		super.onFinishInflate();
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		width = scrollBarPic.getMeasuredWidth();
		height = scrollBarPic.getMeasuredHeight();
		padding = scrollBarPic.getPadding();
		perBarWidth = scrollBarPic.getPerbarWidth();
		initialposition = width - (padding * 7 + perBarWidth * 7);
		leftpadding = getPaddingLeft();
		super.onSizeChanged(w, h, oldw, oldh);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		scrollBarPic.layout(-initialposition + leftpadding, 0, width
				- initialposition + leftpadding, height);
	}

}



package com.miduo.financialmanageclient.ui;

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

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;



/**
 * 单日收益
 * 
 * @author huozhenpeng
 * 
 */
public class SingleDayGainActivity extends BaseActivity implements
		View.OnClickListener {

	private TextView title_txt;
	private ImageView left_img;
	private TextView right_txt;
	private ListView listview;
	private SingleGainAdapter adapter;
	private List datas;
	private ScrollBarPic scrollBarPic;
	private ScrollBarBean scrollBarBean ;
	private ArrayList lists;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_singleday_gain);
		initView();
		initEvent();
		initData();
	}

	private void initData() {
		title_txt.setText("单日收益");
		right_txt.setText("累计收益");
		scrollBarPic = (ScrollBarPic) this.findViewById(R.id.scrollBarPic);
		scrollBarBean = new ScrollBarBean();
		scrollBarBean.setTotal(100);
		lists = new ArrayList();
		lists.add(new ScrollPerBarBean("¥3,000.00", 0, "10-3"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 80, "10-4"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 90, "10-5"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 10, "10-6"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 100, "10-7"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-8"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-9"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-11"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-12"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-13"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-14"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-15"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-16"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-17"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-18"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-19"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-20"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-21"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 55, "10-22"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 56, "10-23"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 80, "10-24"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 90, "10-25"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-26"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 30, "10-27"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 20, "10-28"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 10, "10-29"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "10-30"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 80, "10-31"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 70, "11-1"));
		lists.add(new ScrollPerBarBean("¥3,000.00", 50, "11-2"));
		scrollBarBean.setLists(lists);

		for (int i = 0; i < 4; i++) {
			datas.add(new SingleGainBean(22.34f,
					"米多利产品米多利产品米多利产品米多利产品米多利产品米多利产品"));
		}
		adapter.notifyDataSetChanged();
		
	}

	private void initEvent() {
		title_txt.setOnClickListener(this);
		left_img.setOnClickListener(this);
		scrollBarPic.getViewTreeObserver().addOnGlobalLayoutListener(
				new OnGlobalLayoutListener() {
					@Override
					public void onGlobalLayout() {
						scrollBarPic.setDatas(scrollBarBean);
					}
				});
		scrollBarPic.setOnClickListener(new OnClickListener() {

			@Override
			public void onclick(int i) {
				MToast.showToast(SingleDayGainActivity.this, ""+lists.get(i).getDate());
			}
		});
	}

	private void initView() {
		title_txt = (TextView) this.findViewById(R.id.title_txt);
		left_img = (ImageView) this.findViewById(R.id.left_img);
		right_txt = (TextView) this.findViewById(R.id.right_txt);
		right_txt.setVisibility(View.INVISIBLE);
		listview = (ListView) this.findViewById(R.id.listview);
		scrollBarPic=(ScrollBarPic) this.findViewById(R.id.scrollBarPic);
		datas = new ArrayList();
		adapter = new SingleGainAdapter(datas, this);
		listview.setAdapter(adapter);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.left_img:
			finish();
			break;
		case R.id.right_txt:
			Intent intent=new Intent(this,AssetsListActivity.class);
			startActivity(intent);
			break;

		default:
			break;
		}
	}
}
activity_singleday_gain.xml文件
 
  



    

    

        
    

    

    
    


package com.miduo.financialmanageclient.bean;

import java.io.Serializable;

/**
 * 单日收益页面历史题view的bean对象
 * 
 * @author huozhenpeng
 * 
 */
public class SingleGainBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private float money;
	private String productName;

	public float getMoney() {
		return money;
	}

	public void setMoney(float money) {
		this.money = money;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	@Override
	public String toString() {
		return "SingleGainBean [money=" + money + ", productName="
				+ productName + "]";
	}

	public SingleGainBean(float money, String productName) {
		super();
		this.money = money;
		this.productName = productName;
	}
	

}
package com.miduo.financialmanageclient.bean;

import java.io.Serializable;
/**
 * 
 * @author huozhenpeng
 *
 */
public class ScrollPerBarBean implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String money;// 金额
	private int ratio;
	private String date;// 日期
	private int actualHeight;// 实际高度
	private boolean flag;// 记录是不是点击状态
	private int leftX, rightX, topY;// 记录左右上边距

	public String getMoney() {
		return money;
	}

	public void setMoney(String money) {
		this.money = money;
	}

	public int getRatio() {
		return ratio;
	}

	public void setRatio(int ratio) {
		this.ratio = ratio;
	}

	public String getDate() {
		return date;
	}

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

	public ScrollPerBarBean(String money, int ratio, String date) {
		super();
		this.money = money;
		this.ratio = ratio;
		this.date = date;
	}

	public int getActualHeight() {
		return actualHeight;
	}

	public void setActualHeight(int actualHeight) {
		this.actualHeight = actualHeight;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public int getLeftX() {
		return leftX;
	}

	public void setLeftX(int leftX) {
		this.leftX = leftX;
	}

	public int getRightX() {
		return rightX;
	}

	public void setRightX(int rightX) {
		this.rightX = rightX;
	}

	public int getTopY() {
		return topY;
	}

	public void setTopY(int topY) {
		this.topY = topY;
	}

	@Override
	public String toString() {
		return "PerBarBean [money=" + money + ", ratio=" + ratio + ", date="
				+ date + ", actualHeight=" + actualHeight + ", flag=" + flag
				+ ", leftX=" + leftX + ", rightX=" + rightX + ", topY=" + topY
				+ "]";
	}

}

package com.miduo.financialmanageclient.ui.adapter;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.miduo.financialmanageclient.R;
import com.miduo.financialmanageclient.bean.SingleGainBean;
/**
 * 但是收益listview的adapter
 * @author huozhenpeng
 *
 */
public class SingleGainAdapter extends BaseAdapter {

	private List lists;
	private Context context;

	public SingleGainAdapter(List lists, Context context) {
		super();
		this.lists = lists;
		this.context = context;
	}

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

	@Override
	public Object getItem(int position) {
		return lists.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder viewholder=null;
		if(convertView==null)
		{
			convertView=LayoutInflater.from(context).inflate(R.layout.item_singlegain, null);
			viewholder=new ViewHolder();
			viewholder.tv_money=(TextView) convertView.findViewById(R.id.tv_money);
			viewholder.tv_proname=(TextView) convertView.findViewById(R.id.tv_proname);
			convertView.setTag(viewholder);
		}
		else
		{
			viewholder=(ViewHolder) convertView.getTag();
		}
		viewholder.tv_money.setText(lists.get(position).getMoney()+"");
		viewholder.tv_proname.setText(lists.get(position).getProductName());
		return convertView;
	}

	class ViewHolder {
		TextView tv_proname;
		TextView tv_money;
	}

}



    

        

        

        
    
    






你可能感兴趣的:(Android自定义控件,android)