原来是本人发在52论坛的,因为现在想在CSDN上提问,没有C币,再搬运一次吧,尴尬~!
PS:代码比较乱,因为还在忙另外一个问题,暂时不想整理了,大家将就着看吧
真机运行的时候偶有死机的情况,暂时还不清楚是啥原因
首先是Main_Activity如下
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/img_bg">
//参考博客[url=https://blog.csdn.net/ww897532167/article/details/77334345]https://blog.csdn.net/ww897532167/article/details/77334345[/url]
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/lineChart"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_centerInParent="true"/>
<com.example.cc.simplecharttest.DragFloatActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="16dp"
android:src="@drawable/c_bn">
</com.example.cc.simplecharttest.DragFloatActionButton>
</RelativeLayout>
package com.example.cc.simplecharttest;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import java.util.ArrayList;
import java.util.List;
//import static com.example.cc.simplecharttest.R.id.fab;
import static com.example.cc.simplecharttest.R.id.lineChart;
public class MainActivity extends AppCompatActivity {
private List<String> mlist=new ArrayList<>();
private List<Entry> entries = new ArrayList<>();
private LineChart mLineChart;
private LineDataSet lineDataSet;
private LineData data;
private int ClickTime;
private DragFloatActionButton fab;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ClickTime=3;
//动态加载的问题参考P113
//FloatingActionButton fab=(FloatingActionButton)findViewById(R.id.fab );
fab=(DragFloatActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (ClickTime){
case 1:
ClickTime=ClickTime+1;
Toast.makeText(MainActivity.this,"你操死了潘雯雯1号",Toast.LENGTH_SHORT).show();
break;
case 2:
ClickTime=ClickTime-1;
Toast.makeText(MainActivity.this,"你操死了潘雯雯2号",Toast.LENGTH_SHORT).show();
break;
case 3:
ClickTime=ClickTime-1;
Toast.makeText(MainActivity.this,"你操死了潘雯雯3号",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
});
//隐藏工具栏
ActionBar actionBar=getSupportActionBar();
if (actionBar!=null)
actionBar.hide();
//使状态栏透明
if (Build.VERSION.SDK_INT>=21){
View decorView=getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
mlist.add("一月");
mlist.add("二月");
mlist.add("三月");
mlist.add("四月");
mlist.add("五月");
mlist.add("六月");
mlist.add("七月");
mlist.add("八月");
mlist.add("九月");
mlist.add("十月");
mlist.add("十一月");
mlist.add("十二月");
mlist.add("十三月");
//实例化控件
mLineChart=(LineChart)findViewById(lineChart);
//显示边界
mLineChart.setDrawBorders(true);
//如果为True则背景不能透明,一般为False
mLineChart.setDrawGridBackground(false);
//获取X轴对象
XAxis xAxis=mLineChart.getXAxis();
//下标的位置:BOTTOM,BOTH_SIDED,BOTTOM_INSIDE,TOP,TOP_INSIDE
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
//获取Y轴对象
YAxis leftYAxis=mLineChart.getAxisLeft();
YAxis rightYAxis=mLineChart.getAxisRight();
//得到legend图例,也就是标签的意思
Legend legend=mLineChart.getLegend();
legend.setTextColor(Color.CYAN);
//设置legend位置
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
//设置标签是否换行
legend.setWordWrapEnabled(true);
//隐藏标签
//legend.setEnabled(false);
//隐藏描述
Description description=new Description();
description.setEnabled(false);
mLineChart.setDescription(description);
//设置描述内容
Description description1=new Description();
description1.setText("X轴Description");
description1.setTextColor(Color.RED);
mLineChart.setDescription(description1);
//设置Y轴值
leftYAxis.setAxisMinimum(0f);
leftYAxis.setAxisMaximum(100f);
rightYAxis.setAxisMinimum(0f);
rightYAxis.setAxisMaximum(100f);
leftYAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return (int)value+"%";
}
});
//Y轴右侧不显示
rightYAxis.setEnabled(false);
leftYAxis.setGranularity(1f);
leftYAxis.setLabelCount(11,false);
leftYAxis.setTextColor(Color.BLUE);//文字颜色
leftYAxis.setGridColor(Color.RED);//网格线颜色
leftYAxis.setAxisLineColor(Color.GREEN);//Y轴颜色
//限制线LimitLine
LimitLine limitLine1=new LimitLine(70,"上高限制性");//限制线
limitLine1.setLineWidth(4f);//宽度
limitLine1.setTextColor(Color.RED);
limitLine1.setTextSize(4f);
limitLine1.setLineColor(Color.BLUE);
leftYAxis.addLimitLine(limitLine1);//右边Y轴添加限制线
LimitLine limitLine2=new LimitLine(50,"下高限制性");//限制线
limitLine2.setLineWidth(4f);//宽度
limitLine2.setTextColor(Color.RED);
limitLine2.setTextSize(4f);
limitLine2.setLineColor(Color.BLUE);
leftYAxis.addLimitLine(limitLine2);//右边Y轴添加限制线
/*//设置X轴的值(最小值、最大值、然后会根据设置的刻度数量自动分配刻度显示)
xAxis.setAxisMinimum(0f);
xAxis.setAxisMaximum(13f);*/
//设置X轴下标最小间隔
xAxis.setGranularity(1f);
//设置X轴的刻度数量,true是按比例分配,false是适配X刻度值分配
xAxis.setLabelCount(13,true);
//设置X轴值为字符串,一次一月到12月
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return mlist.get((int)value);
}
});
//定义数组,设置数据
//List<Entry> entries = new ArrayList<>();
for (int i = 0; i < 13; i++)
//产生10个点并赋值,相当于第一个是横轴坐标值,第二个是竖轴坐标值
entries.add(new Entry(i, (float) (Math.random()) * 80));
//曲线数据集
lineDataSet = new LineDataSet(entries, "温度");
//取消曲线显示的值为整数与设置自定义X轴类似。设置曲线显示值为整数,可在设置曲线LineDataSet 时,修改值的类型
/*lineDataSet.setValueFormatter(new IValueFormatter() {
@Override
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
int IValue=(int)value;
return String.valueOf(IValue);
}
});*/
//LineChart的数据源
data = new LineData(lineDataSet);
//chart装入数据
mLineChart.setData(data);
//视图更新,没有这一步,曲线不会呈现动态
//mLineChart.invalidate();
//点击弹框
MyMarkerView mv = new MyMarkerView(MainActivity.this);
mLineChart.setMarker(mv);//有失效方法
mLineChart.setTouchEnabled(false);
//启动服务
/*Intent intent=new Intent(this,MyService.class);
startService(intent);*/
/*Entry entry = new Entry(lineDataSet.getEntryCount(), number);
lineData.addEntry(entry, 0);
//通知数据已经改变
lineData.notifyDataChanged();
mLineChart.notifyDataSetChanged();
//设置在曲线图中显示的最大数量
mLineChart.setVisibleXRangeMaximum(10);
//移到某个位置
mLineChart.moveViewToX(lineData.getEntryCount() - 5);*/
new MyThread().start();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
/*重置floatActionBar位置否则容易找不到
fab.setX(100);
fab.setY(100);*/
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
Toast.makeText(this,"当前屏幕为竖屏会影响效果,建议横屏观看",Toast.LENGTH_SHORT).show();
super.onConfigurationChanged(newConfig);
}
class MyThread extends Thread{
@Override
public void run() {
while (true){try {
Thread.sleep(2000);
}catch (InterruptedException e){
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
//逻辑
//定义数组,设置数据
entries.clear();
mLineChart.clear();
for (int i = 0; i < 13; i++)
//产生10个点并赋值,相当于第一个是横轴坐标值,第二个是竖轴坐标值
entries.add(new Entry(i, (float) (Math.random()) * 80));
//曲线数据集
lineDataSet = new LineDataSet(entries, "温度");
data = new LineData(lineDataSet);
//通知数据已经改变
mLineChart.setData(data);
}
});
}
}
}
}
//参考网站[url=https://blog.csdn.net/ww897532167/article/details/74139843]https://blog.csdn.net/ww897532167/article/details/74139843[/url]
下面关键代码,测量屏幕的大小,以便可以随意拖动DragBarTool
package com.example.cc.simplecharttest;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;
import java.lang.reflect.Method;
/**
* Created by cc on 2018/6/9.
*/
public class ScreenUtils {
private ScreenUtils(){
//不让被实例化??
throw new UnsupportedOperationException("cannot be instantiated");
}
//获取屏幕宽度
public static int getScreenWidth(Context context){
//获取实例
WindowManager wm=(WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
//不包括下方虚拟按键
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.widthPixels;
}
//获取屏幕宽度
public static int getScreenHeight(Context context){
//获取实例
WindowManager wm=(WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
//不包括下方虚拟按键
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
}
//获取状态栏的高度
public static int getStatusHeight(Context context){
int statusHeight=-1;
try{
//获取类,反射方法
Class<?> clazz=Class.forName("com.android.internal.R$dimen");
//实例化类
Object object=clazz.newInstance();
int height=Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
statusHeight=context.getResources().getDimensionPixelSize(height);
}catch (Exception e)
{e.printStackTrace();}
return statusHeight;
}
//获取虚拟功能键高度
public static int getVirtualBarHeigh(Context context) {
//虚拟功能键的高
int vh = 0;
//虚拟功能键的宽
int vw=0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
//获取屏幕信息
Display display = windowManager.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
try {
//反射
@SuppressWarnings("rawtypes")
Class c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
//getRealMetrics(display, dm)
method.invoke(display, dm);
//vh = dm.heightPixels - windowManager.getDefaultDisplay().getHeight();//有替代方法,下面三行就是
windowManager.getDefaultDisplay().getMetrics(dm);
vh=dm.heightPixels;
vw=dm.widthPixels;
} catch (Exception e) {
e.printStackTrace();
}
return vh;
}
//获取标题栏高度
public static int getVirtualBarHeigh(Activity activity) {
int titleHeight = 0;
Rect frame = new Rect();
//getDecorView()的意思是当前窗口的根View
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
//标题高度
int statusHeight = frame.top;
//Window.ID_ANDROID_CONTENT表示视图的内容部分
titleHeight = activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop() - statusHeight;
//返回标题的高度
return titleHeight;
}
}
下面是注册拖动控件
package com.example.cc.simplecharttest;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.support.design.widget.FloatingActionButton;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.animation.BounceInterpolator;
/**
* Created by cc on 2018/6/9.
*/
public class DragFloatActionButton extends FloatingActionButton {
private int screenWidth;
private int screenHeight;
private int screenWidthHalf;
private int statusHeight;
private int virtualHeight;
private int lastX;
private int lastY;
private boolean isDrag;
public DragFloatActionButton(Context context){
super(context);
init();
}
public DragFloatActionButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DragFloatActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
screenWidth = ScreenUtils.getScreenWidth(getContext());
screenWidthHalf = screenWidth / 2;
screenHeight = ScreenUtils.getScreenHeight(getContext());
statusHeight = ScreenUtils.getStatusHeight(getContext());
virtualHeight=ScreenUtils.getVirtualBarHeigh(getContext());
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int rawX = (int) ev.getRawX();
int rawY = (int) ev.getRawY();
//处理多点触摸事件
switch (ev.getAction()&MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
isDrag=false;
//取得焦点,可以接受事件,当传入的参数为true时,表示子组件要自己消费这次事件,告诉父组件不要拦截(抢走)这次的事件
//对于底层的View来说,有一种方法可以阻止父层的View截获touch事件,就是调用getParent().requestDisallowInterceptTouchEvent(true);方法。一旦底层View收到touch的action后调用这个方法那么父层View就不会再调用onInterceptTouchEvent了,也无法截获以后的action。
getParent().requestDisallowInterceptTouchEvent(true);
lastX = rawX;
lastY = rawY;
break;
case MotionEvent.ACTION_MOVE:
isDrag = true;
//计算手指移动了多少
int dx = rawX - lastX;
int dy = rawY - lastY;
//这里修复一些手机无法触发点击事件的问题
int distance= (int) Math.sqrt(dx*dx+dy*dy);
if(distance<3){//给个容错范围,不然有部分手机还是无法点击
isDrag=false;
break;
}
float x = getX() + dx;
float y = getY() + dy;
//检测是否到达边缘 左上右下
x = x < 0 ? 0 : x > screenWidth - getWidth() ? screenWidth - getWidth() : x;
Log.d("move---->", "屏幕宽度screenwidth"+screenWidth+"getwidth宽度"+getWidth()+"屏幕高度screenheight"+screenHeight);
//y = y < statusHeight ? statusHeight : (y + getHeight() >= screenHeight ? screenHeight - getHeight() : y);
if (y<0){
y=0;
}
//getHeight()本身的高度
if (y>screenHeight-getHeight()){
y=screenHeight-getHeight();
}
setX(x);
setY(y);
lastX = rawX;
lastY = rawY;
Log.e("move---->", "getX=" + getX() + ";screenWidthHalf=" + screenWidthHalf + " " + isDrag+" statusHeight="+statusHeight+ " virtualHeight"+virtualHeight+ " screenHeight"+ screenHeight+" getHeight="+getHeight()+" y"+y);
break;
//在UP里添加吸附功能
case MotionEvent.ACTION_UP:
if (isDrag) {
//恢复按压效果
setPressed(false);
Log.e("ACTION_UP---->", "getX=" + getX() + ";screenWidthHalf=" + screenWidthHalf);
if (rawX >= screenWidthHalf) {
//设置动画效果,设置动画为减速动画(动画播放中越来越慢)向左吸附
animate().setInterpolator(new BounceInterpolator())
.setDuration(155)//设置动画时间
.xBy(screenWidth - getWidth() - getX())//啥意思?不懂
.start();
} else {
//动画Float型平滑过渡(向右吸附)
ObjectAnimator oa = ObjectAnimator.ofFloat(this, "x", getX(), 0);//“x”是啥意思不懂
oa.setInterpolator(new BounceInterpolator());
oa.setDuration(155);//设置动画时间
oa.start();
}
}
Log.e("up---->",isDrag+"");
break;
}
return isDrag ||super.onTouchEvent(ev);
}
}
build.gradle代码
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "27.0.0"
defaultConfig {
applicationId "com.example.cc.simplecharttest"
minSdkVersion 23
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.github.PhilJay:MPAndroidChart:v3.0.2'
compile 'com.android.support:design:26+'
testCompile 'junit:junit:4.12'
}