摘要:啟用禁用與圖表的所有可能的觸摸交互。禁止繪制右坐標軸軸數據設置為,則繪制網格線。每次動態更改數據時若不調用此方法可能導致崩潰或意外行為。
其中包括
1.新大陸閉包:用于連接新大陸云平臺,通過底層硬件設備獲取數據,并上傳至云平臺,移動端端通過此閉包,連接云平臺,實時獲取數據
2.Google推出的MaterialDesign API
3.MPAndroidChar:繪制折線圖等
implementation project(path: ":nlecloud-sdk") implementation "com.google.android.material:material:1.1.0-alpha09" implementation "com.getbase:floatingactionbutton:1.10.1" implementation "com.google.android.material:material:1.0.0" implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
因為要與獲取云平臺數據,所有申明網絡權限
Google表示,為保證用戶數據和設備的安全,針對下一代 Android 系統(Android P) 的應用程序,將要求默認使用加密連接,這意味著 Android P 將禁止 App 使用所有未加密的連接,因此運行 Android P 系統的安卓設備無論是接收或者發送流量,未來都不能明碼傳輸,需要使用下一代(Transport Layer Security)傳輸層安全協議,而 Android Nougat 和 Oreo 則不受影響。
在Android Studio,res目錄下創建一個xml包,再在xml包內創建一個network_security_config.xml文件(文件名自定義)
res->xml->network_security_config.xml
代碼如下:
然后在清單文件中引用
android:networkSecurityConfig="@xml/network_security_config"
右上角按鈕數字從5開始倒計時,采用Handler異步通信實現,到0時,自動跳轉到登錄界面,代碼如下:
Handler handler = new Handler( ){ @Override public void handleMessage(@NonNull Message msg) { super.handleMessage( msg ); if (msg.what == 0 && Flag) { int Count = CountDown(); btn_Skip.setText( "跳過 " + Count ); handler.sendEmptyMessageDelayed( 0,1000 ); } } };
代碼中Flag用于Handler倒計時未結束,點擊按鈕進行跳轉,異步通信未結束,防止再次渲染
** * Author:FranzLiszt * Completion time:9-20*/public class WelComeActivity extends AppCompatActivity { private Button btn_Skip,GetInto; private int TotalNumber = 5; /*用于點擊跳過或者進入應用按鈕之后,界面發生跳轉,但線程并未停止,時間到達,仍會重新渲染一次, 使用此標志,用來控制不執行異步介紹的信息,從此達到中斷的效果*/ private boolean Flag = true; Handler handler = new Handler( ){ @Override public void handleMessage(@NonNull Message msg) { super.handleMessage( msg ); if (msg.what == 0 && Flag) { int Count = CountDown(); btn_Skip.setText( "跳過 " + Count ); handler.sendEmptyMessageDelayed( 0,1000 ); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate( savedInstanceState ); 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 ); } setContentView( R.layout.activity_wel_come ); InitView(); } /*5s之后自動跳轉*/ private void InitView(){ btn_Skip = findViewById( R.id.btn_Skip ); GetInto = findViewById( R.id.GetInto); handler.sendEmptyMessageDelayed( 0,1000 ); } private int CountDown(){ if (TotalNumber -- == 1){ ReturnActivity(LoginActivity.class); } return TotalNumber; } public void Skip(View view) { Flag = false; ReturnActivity(LoginActivity.class); } public void GetIntoApp(View view) { Flag = false; ReturnActivity(LoginActivity.class); } private void ReturnActivity(Class Activity){ startActivity( new Intent( WelComeActivity.this,Activity ) ); }}
UI部分采用Google的MD組件庫,此處省略,代碼部分,主要獲取用戶輸入的賬戶、密碼傳輸給云平臺進行匹配,如果密碼正確,服務器會返回一個AccessToken(訪問令牌)JSON數據,然后我們進行反序列化,使用此令牌進行后續操作
獲取AccessToken之后,通過SharedPreferences封裝類SP進行保存(SP封裝類在另一篇博文中有詳細解鎖,此處省略
https://editor.csdn.net/md/?articleId=120434977
public class LoginActivity extends AppCompatActivity { private EditText mUserName,mPassWord; private String AccessToken = ""; private SP sp; private NetWorkBusiness business; private Context context = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate( savedInstanceState ); 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 ); } setContentView( R.layout.activity_login ); InitView(); } private void InitView(){ mUserName = findViewById( R.id.username ); mPassWord = findViewById( R.id.password ); if (context == null){ context = LoginActivity.this; } } private void LoginMethod(){ String UserName = mUserName.getText().toString().trim(); String PassWord = mPassWord.getText().toString().trim(); if (TextUtils.isEmpty( UserName )){ Toast.makeText( context,"UserName cannot be empty",Toast.LENGTH_SHORT ).show(); return; } if (TextUtils.isEmpty( PassWord )){ Toast.makeText( context,"PassWord cannot be empty",Toast.LENGTH_SHORT ).show(); return; } business = new NetWorkBusiness( AccessToken, Param.URL ); business.signIn( new SignIn( UserName, PassWord ), new NCallBack>(getApplicationContext()) { @Override protected void onResponse(BaseResponseEntity response) { } @Override public void onResponse(Call> call, Response> response) { super.onResponse( call, response ); BaseResponseEntity body = response.body(); if (body != null && body.getStatus() == 0){ sp = new SP( context ); AccessToken = body.getResultObj().getAccessToken(); /*將AccessToken存入sp*/ sp.PutData( context,"AccessToken",AccessToken ); ReturnActivity(MainActivity.class); Toast.makeText( context,"Login Success",Toast.LENGTH_SHORT ).show(); }else { Toast.makeText( context,"Login Fail",Toast.LENGTH_SHORT ).show(); } } @Override public void onFailure(Call> call, Throwable t) { super.onFailure( call, t ); Toast.makeText( context,"Exception",Toast.LENGTH_SHORT ).show(); } } ); } /*標題欄返回按鈕*/ public void Exit(View view){ ReturnActivity(WelComeActivity.class); } /*登錄按鈕*/ public void Login(View view){ LoginMethod(); } private void ReturnActivity(Class Activity){ startActivity( new Intent( context,Activity ) ); }}
頂部兩個圓形進度條會根據傳入的數據,發生相對應變化
樣式變化規則如下:
/** * Author:FranzLiszt * Function:排隊叫號 * Tips:設置最多排隊20個人,超過20人會實時顯示,但不會聯動觸發樣式效果 * 10人及以下外圓弧與文字為綠色 * 11-20人外圓弧與文字為紫色 * 大于20及,外圓弧與文字為紅色 * 硬件沒有限制,軟件限制人數*//** * 核心思想: * 取號:獲取一個號碼,開始排隊 * 叫號:當前方排隊人數小于3時,系統提示請前往現場辦理業務,無需進行排隊,所有功能置灰*/public class MainActivity extends AppCompatActivity { /*圓形進度條上方提示文字 * 作用:跟隨進度條外圓弧顏色的變化而變化*/ private TextView Text_CurrentPeople,Text_CurrentTime; /*圓形進度條 * 作用:外圓弧跟隨排隊人數與剩余時間的變化而變化*/ private ProgressBarView CurrentPeople,CurrentTime; /*需要輸入的內容*/ private EditText InputMessage; /*按鍵*/ private Button SendMessage,ReadProgress,ReadRecord,LineUp,CancelLineUp; private RelativeLayout TipLayout; private TextView TipText,btn_Agree,pop_TipText,pop_TipAgree; private SP sp; private String AccessToken = ""; private NetWorkBusiness business; private Context context = null; /*用來判斷是否取消排隊,中斷線程*/ private boolean Flag = true; /*用來裝載獲取服務器的排隊人數*/ private int mCurrentNumber; /*用來裝載獲取服務器的等候時間 * 時間 = 人數 * 5 * 基數自定義*/ private int mCurrentWaitTime; /*用來判斷是否正在排隊,如果正在排隊,排隊按鈕無法點擊*/ private boolean EnableFlag = false; private Thread thread; private boolean DialogFlag = true; private PopupWindow mPopupWindow,mPopupWindow_2; private View TipView,TipView_2; private static final int COMPLETE = 2; private static final int START = 1; private static final int STOP = 0; Handler handler = new Handler( ){ @Override public void handleMessage(@NonNull Message msg) { super.handleMessage( msg ); switch (msg.what){ case COMPLETE: CompleteQueuing(); break; case START: GetAndSet(); break; case STOP: clearStyle(); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate( savedInstanceState ); 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 ); } setContentView( R.layout.activity_main ); InitView(); GetSpValue(); Listener(); GetCurrentPeople(); InitPopWidows(); } /** * Name:InitView * Function:初始化控件*/ private void InitView(){ Text_CurrentPeople = findViewById( R.id.Text_CurrentPeople ); Text_CurrentTime = findViewById( R.id.Text_CurrentTime ); InputMessage = findViewById( R.id.InputMessage ); SendMessage = findViewById( R.id.SendMessage ); ReadProgress = findViewById( R.id.ReadProgress ); ReadRecord = findViewById( R.id.ReadRecord ); LineUp = findViewById( R.id.btn_LineUp ); CancelLineUp = findViewById( R.id.btn_CancelLineUp ); CurrentPeople = findViewById( R.id.CurrentPeople ); CurrentTime = findViewById( R.id.CurrentTime ); TipLayout = findViewById( R.id.TipLayout ); TipText = findViewById( R.id.TipText ); if (context == null){ context = MainActivity.this; } LineUp.setBackgroundResource( R.drawable.btn_notenable ); LineUp.setEnabled( false ); } /** * Name:GetSpValue * Function:獲取AccessToken * 實例化NetWorkBusiness對象*/ private void GetSpValue(){ sp = new SP( context ); AccessToken = (String) sp.GetData( context,"AccessToken","" ); business = new NetWorkBusiness( AccessToken, Param.URL ); } private void GetCurrentPeople(){ thread = new Thread( ){ @Override public void run() { super.run(); while (true) { while (Flag) { try { Thread.sleep( 3000 ); } catch (InterruptedException e) { e.printStackTrace(); } Message message = new Message(); message.what = START; handler.sendMessage( message ); } } } }; thread.start(); } private void GetAndSet(){ business.getSensors( Param.DEVICEID, Param.QUEUENUMBER, new NCallBack>>(context) { @Override protected void onResponse(BaseResponseEntity> response) { } @Override public void onResponse(Call>> call, Response>> response) { super.onResponse( call, response ); BaseResponseEntity> body = response.body(); if (body!=null && body.getStatus() == 0){ mCurrentNumber = Integer.parseInt( body.getResultObj().get( 0 ).getValue() ); mCurrentWaitTime = mCurrentNumber * 5; sp.PutData( context,"CurrentNumber",mCurrentNumber ); sp.PutData( context,"CurrentWaitTime",mCurrentWaitTime ); } } } ); runOnUiThread( ()->{ if (mCurrentNumber >= 20){ /*人數大于20,紅色*/ setRed(); DialogFlag = true; DisplayLayout_Queuing(); }else if (mCurrentNumber < 20 && mCurrentNumber > 10 ){ /*人數10-20,紫色*/ setViolet(); DialogFlag = true; DisplayLayout_Queuing(); }else if (mCurrentNumber <= 10 && mCurrentNumber > 3){ /*人數小于10,綠色*/ setGreen(); DialogFlag = true; DisplayLayout_Queuing(); }else if (mCurrentNumber <=3 && mCurrentNumber > 0){ if (DialogFlag){ Flag = false; Message message = new Message(); message.what = COMPLETE; handler.sendMessage( message ); } } } ); } private void Control(String DeviceID,String Tag,Object value){ business.control( DeviceID, Tag, value, new NCallBack(getApplicationContext()) { @Override protected void onResponse(BaseResponseEntity response) { } @Override public void onResponse(Call call, Response response) { super.onResponse( call, response ); BaseResponseEntity body = response.body(); if (body == null && body.getStatus() != 0){ Toast.makeText( context,"請求失敗",Toast.LENGTH_SHORT ).show(); } } @Override public void onFailure(Call call, Throwable t) { super.onFailure( call, t ); Toast.makeText( context,"異常",Toast.LENGTH_SHORT ).show(); } } ); } private void SendVoiceMessage(){ String Message = InputMessage.getText().toString().trim(); Control( Param.DEVICEID,Param.VOIVE,Message ); } private void InitPopWidows(){ TipView = LayoutInflater.from( context ).inflate( R.layout.pop_item,null ); btn_Agree = TipView.findViewById( R.id.btn_Agree ); mPopupWindow = new PopupWindow( TipView, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT ); mPopupWindow.setFocusable( true ); //獲取焦點 mPopupWindow.setBackgroundDrawable( new BitmapDrawable() ); mPopupWindow.setOutsideTouchable( true ); //點擊外面地方,取消 mPopupWindow.setTouchable( true ); //允許點擊 mPopupWindow.setAnimationStyle( R.style.PopupWindow ); //設置動畫 btn_Agree.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { //EnableFlag = true; setGrey(); setStyleInvalid(); setButtonNotEnabled(); /*手機震動*/ Vibrator vibrator = (Vibrator) getSystemService( Service.VIBRATOR_SERVICE); vibrator.vibrate(100); mPopupWindow.dismiss(); } } ); TipView_2 = LayoutInflater.from( context ).inflate( R.layout.tip_pop_item,null ); pop_TipText = TipView_2.findViewById( R.id.pop_TipsText ); pop_TipAgree = TipView_2.findViewById( R.id.pop_TipAgree ); mPopupWindow_2 = new PopupWindow( TipView_2, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT ); mPopupWindow_2.setFocusable( true ); //獲取焦點 mPopupWindow_2.setBackgroundDrawable( new BitmapDrawable() ); mPopupWindow_2.setOutsideTouchable( true ); //點擊外面地方,取消 mPopupWindow_2.setTouchable( true ); //允許點擊 mPopupWindow_2.setAnimationStyle( R.style.PopupWindow ); //設置動畫 pop_TipAgree.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { mPopupWindow_2.dismiss(); } } ); } private void DisPlayPopWindows(){ mPopupWindow.showAtLocation( TipView, Gravity.CENTER,0,0 ); } private void ShowPopWindows(){ pop_TipText.setText( "目前前方剩余"+mCurrentNumber+"人,需要等候"+mCurrentWaitTime+"min" ); mPopupWindow_2.showAtLocation( TipView_2,Gravity.CENTER,0,0 ); } private void DisplayLayout_Queuing(){ TipLayout.setVisibility( View.VISIBLE ); TipText.setText( "當前正在排隊中,請文明排隊" ); } private void DisplayLayout_CancelQueuing(){ TipLayout.setVisibility( View.VISIBLE ); TipText.setText( "當前號碼已作廢,請重新排隊" ); } private void DisplayLayout_CallNumber(){ TipLayout.setVisibility( View.VISIBLE ); TipText.setText( "排隊完成,請前往現場辦理業務" ); } private void CompleteQueuing(){ /*人數小于3,給予提示*/ DisplayLayout_CallNumber(); DisPlayPopWindows(); } private void setRed(){ Text_CurrentPeople.setTextColor( getResources().getColor( R.color.colorRed ) ); Text_CurrentTime.setTextColor( getResources().getColor( R.color.colorRed ) ); Text_CurrentPeople.setText( mCurrentNumber+getResources().getString( R.string.Tips_2 ) ); Text_CurrentTime.setText( mCurrentWaitTime+"Min" ); CurrentPeople.setProgress( 100 ); CurrentPeople.setCircleColor( getResources().getColor( R.color.colorRed ) ); CurrentPeople.setContent( "擁擠" ); CurrentTime.setProgress( 100 ); CurrentTime.setCircleColor( getResources().getColor( R.color.colorRed ) ); CurrentTime.setContent( "時間長" ); } private void setViolet(){ Text_CurrentPeople.setTextColor( getResources().getColor( R.color.colorViolet ) ); Text_CurrentTime.setTextColor( getResources().getColor( R.color.colorViolet ) ); Text_CurrentPeople.setText( mCurrentNumber+getResources().getString( R.string.Tips_2 ) ); Text_CurrentTime.setText( mCurrentWaitTime+"Min" ); CurrentPeople.setProgress( mCurrentWaitTime ); CurrentPeople.setCircleColor( getResources().getColor( R.color.colorViolet ) ); CurrentPeople.setContent( "正常" ); CurrentTime.setProgress( mCurrentWaitTime ); CurrentTime.setCircleColor( getResources().getColor( R.color.colorViolet ) ); CurrentTime.setContent( "時間中" ); } private void setGreen(){ Text_CurrentPeople.setTextColor( getResources().getColor( R.color.colorGreen ) ); Text_CurrentTime.setTextColor( getResources().getColor( R.color.colorGreen ) ); Text_CurrentPeople.setText( mCurrentNumber+getResources().getString( R.string.Tips_2 ) ); Text_CurrentTime.setText( mCurrentWaitTime+"Min" ); CurrentPeople.setProgress( mCurrentWaitTime ); CurrentPeople.setCircleColor( getResources().getColor( R.color.colorGreen ) ); CurrentPeople.setContent( "暢通" ); CurrentTime.setProgress( mCurrentWaitTime ); CurrentTime.setCircleColor( getResources().getColor( R.color.colorGreen ) ); CurrentTime.setContent( "時間短" ); } private void setGrey(){ Text_CurrentPeople.setTextColor( getResources().getColor( R.color.colorGrey ) ); Text_CurrentTime.setTextColor( getResources().getColor( R.color.colorGrey ) ); Text_CurrentPeople.setText( "0"+getResources().getString( R.string.Tips_2 ) ); Text_CurrentTime.setText( "0 Min" ); CurrentPeople.setProgress( 0 ); CurrentPeople.setCircleColor( getResources().getColor( R.color.colorGrey ) ); CurrentPeople.setContent( "無" ); CurrentTime.setProgress( 0 ); CurrentTime.setCircleColor( getResources().getColor( R.color.colorGrey ) ); CurrentTime.setContent( "無" ); } /*按鈕不能點擊*/ private void setButtonNotEnabled(){ SendMessage.setEnabled( false ); ReadProgress.setEnabled( false ); ReadRecord.setEnabled( false ); CancelLineUp.setEnabled( false ); InputMessage.setEnabled( false ); LineUp.setEnabled( true ); InputMessage.setText( "" ); } /*樣式灰色*/ private void setStyleInvalid(){ SendMessage.setBackgroundResource( R.drawable.btn_notenable ); ReadProgress.setBackgroundResource( R.drawable.btn_notenable ); ReadRecord.setBackgroundResource( R.drawable.btn_notenable ); CancelLineUp.setBackgroundResource( R.drawable.btn_notenable ); LineUp.setBackgroundResource( R.drawable.btn_login ); } /*樣式恢復正常*/ private void setNormalStyle(){ SendMessage.setBackgroundResource( R.drawable.btn_login ); ReadProgress.setBackgroundResource( R.drawable.btn_login ); ReadRecord.setBackgroundResource( R.drawable.btn_login ); CancelLineUp.setBackgroundResource( R.drawable.btn_login ); LineUp.setBackgroundResource( R.drawable.btn_notenable ); } /*按鈕允許點擊*/ private void setButtonEnabled(){ SendMessage.setEnabled( true ); ReadProgress.setEnabled( true ); ReadRecord.setEnabled( true ); CancelLineUp.setEnabled( true ); InputMessage.setEnabled( true ); LineUp.setEnabled( false ); } private void NormalStyle(){ DialogFlag = false; Flag = true; setNormalStyle(); setButtonEnabled(); Message message = new Message(); message.what = START; handler.sendMessage( message ); } /*排隊取消狀態 * 所有控件置灰*/ private void clearStyle(){ Flag = false; DisplayLayout_CancelQueuing(); setGrey(); setButtonNotEnabled(); setStyleInvalid(); } private void StopThread(){ Flag = false; try { thread.join( 1000 ); } catch (InterruptedException e) { e.printStackTrace(); } Message message = new Message(); message.what = STOP; handler.sendMessage( message ); } /*返回按鈕*/ public void Exit(View view){ ReturnActivity( LoginActivity.class ); } private void ReturnActivity(Class Activity){ startActivity( new Intent( context,Activity ) ); } private void Listener(){ OnClick onClick = new OnClick(); SendMessage.setOnClickListener( onClick ); ReadRecord.setOnClickListener( onClick ); ReadProgress.setOnClickListener( onClick ); LineUp.setOnClickListener( onClick ); CancelLineUp.setOnClickListener( onClick ); } class OnClick implements View.OnClickListener{ @Override public void onClick(View v) { switch (v.getId()){ case R.id.SendMessage: SendVoiceMessage(); break; case R.id.btn_LineUp: NormalStyle(); break; case R.id.btn_CancelLineUp: StopThread(); break; case R.id.ReadProgress: ShowPopWindows(); break; case R.id.ReadRecord: ReturnActivity( HistoricalDataActivity.class ); break; } } }}
通過在子線程實時獲取數據,然后通過runOnUiThread跳轉到主線程,實時更新UI,具體使用此處省略,代碼基本每句都有注釋
public class HistoricalDataActivity extends AppCompatActivity { private LineChart LineChart; private String[] mDate; private LineData mLineData; // 線集合,所有折線以數組的形式存到此集合中 private LineDataSet mDataSet; // 點集合,即一條折線 private List mEntries; // Entry為某條折線上的一個點,其List封裝于LineDataSet中 private Timer mTimer; // 定時器,動態獲取數據 private NetWorkBusiness mNetWorkBusiness; private String mAccessToken; private SP sp; private Context context = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate( savedInstanceState ); 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 ); } setContentView( R.layout.activity_historical_data ); InitView(); InitLineChart(); } private void InitView(){ LineChart = findViewById( R.id.LineChart ); if (context == null){ context = HistoricalDataActivity.this; } sp = new SP( context ); mAccessToken = (String) sp.GetData( context,"AccessToken","" ); mNetWorkBusiness = new NetWorkBusiness( mAccessToken, Param.URL ); } public void Exit(View view){ startActivity( new Intent( context,MainActivity.class ) ); } private void InitLineChart(){ LineChart.getDescription().setText("時間");//設置圖表的描述文字,會顯示在圖表的右下角。 LineChart.getLegend().setEnabled(false); LineChart.setTouchEnabled(true);//啟用/禁用與圖表的所有可能的觸摸交互。 LineChart.setDragEnabled(true);//啟用/禁用拖動(平移)圖表。 LineChart.setScaleEnabled(true);//啟用/禁用縮放圖表上的兩個軸。 LineChart.setDrawGridBackground(true);//如果啟用,chart繪圖區后面的背景矩形將繪制。 LineChart.setPinchZoom(false);//如果設置為true,沒縮放功能。如果false,x軸和y軸可分別放大。 LineChart.setBackgroundColor(getResources().getColor( R.color.colorWhite ));//設置背景顏色,將覆蓋整個圖表視圖。此外,背景顏色可以在布局文件.xml中進行設置。 LineChart.setBorderColor( getResources().getColor( R.color.colorBlue_1 ) );//設置chart邊框線的顏色 LineChart.setBorderWidth( 1 );//setBorderWidth(float width):設置chart邊界線的寬度,單位dp。 LineChart.getAxisRight().setEnabled(false);// 禁止繪制右坐標軸 /*X軸數據*/ XAxis xAxis = LineChart.getXAxis(); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setDrawGridLines(false);//設置為true,則繪制網格線。 xAxis.setLabelCount(5,false); // force:false,僅建議刻度線標簽的數量為10 xAxis.setTextSize(5); xAxis.setGridColor( getResources().getColor( R.color.colorViolet) ); xAxis.setValueFormatter( new ValueFormatter() { @Override public String getFormattedValue(float value) { return mDate[(int) value]; } } ); /*Y軸數據*/ YAxis yAxis = LineChart.getAxisLeft(); yAxis.setAxisMinimum(0f); // 設置y軸的坐標最小值為0(人數不小于0) yAxis.setGranularity(1f); // 設置y軸的坐標之間的最小間隔為1(單位:人) yAxis.setLabelCount(10, false); // force:false,僅建議刻度線標簽的數量為12 yAxis.setGridColor(getResources().getColor( R.color.colorViolet)); mEntries = new ArrayList(); mDataSet = new LineDataSet(mEntries, "排隊人數"); mDataSet.setDrawCircles(true); // 禁止繪制折線圓點 mDataSet.setHighlightEnabled(true); // 禁止高亮選中點 mDataSet.setColor(getResources().getColor( R.color.colorBlue_1)); // 折線顏色 mDataSet.setValueFormatter(new ValueFormatter() { @Override public String getFormattedValue(float value) { return ""; } }); mLineData = new LineData(mDataSet); LineChart.setData(mLineData); LineChart.invalidate(); // 更新視圖 mTimer = new Timer( ); mTimer.schedule( new TimerTask() { @Override public void run() { mNetWorkBusiness.getSensorData( Param.DEVICEID, Param.QUEUENUMBER, "1", "1", null, null, "ASC", "10", "1", new NCallBack>(context) { @Override protected void onResponse(BaseResponseEntity response) { } @Override public void onResponse(Call> call, Response> response) { super.onResponse( call, response ); List body = response.body().getResultObj().DataPoints; if (body == null){ return; }else { List list = body.get(0).PointDTO; SensorDataPageDTO.VR[] array = new SensorDataPageDTO.VR[list.size()]; list.toArray(array); mDataSet.clear(); mDate = new String[array.length]; // = 0; for (int idx = 0; idx < array.length; idx++) { mDate[idx] = array[idx].RecordTime; mDataSet.addEntry(new Entry((float) idx, Float.parseFloat(array[idx].Value))); } runOnUiThread( ()->{ // 通知LinData數據已發生變更,以重新計算繪制參數 LineChart.getLineData().notifyDataChanged(); // 讓ChartLine知道其基礎數據已更改,并執行所有必要的計算。每次動態更改數據時,若不調用此方法可能導致崩潰或意外行為。 LineChart.notifyDataSetChanged(); LineChart.invalidate(); } ); } } } ); } },100,2000 ); } @Override protected void onDestroy() { super.onDestroy(); mTimer.cancel(); }}
路漫漫其修遠兮,吾將上下而求索
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/120930.html
摘要:今天凌晨的開發者大會不像以往的歷屆,貌似今年的人工智能和智能家居搶走了系統的風頭。這次在開發者大會上還推出了功能。,是迄今為止最全面的移動開發者平臺。谷歌在此次大會上發布了全新的工具。 今天凌晨的Google I/O開發者大會不像以往的歷屆,貌似今年的人工智能和智能家居搶走了Android系統的風頭。以往每年應該都是 Android 新系統的發布才是重點??磥砣斯ぶ悄芎吞摂M現實確實是未...
摘要:昨日,谷歌桑達爾皮查伊在中國發展高層論壇中,表露出希望借助重返中國大陸市場的愿望,他說將重塑我們的未來,而中國已經在這一過程中發揮重要作用。谷歌方面還暗示,如果政策允許,會考慮云服務進軍中國內地市場。昨日,谷歌CEO桑達爾·皮查伊(Sundar Pichai)在中國發展高層論壇中,表露出希望借助AI重返中國大陸市場的愿望,他說:AI將重塑我們的未來,而中國已經在這一過程中發揮重要作用。當我們...
摘要:阿帕云引擎怎么樣阿帕云引擎是原系統,集于星外主機系統宏杰主機管理系統于三方技術于一身,目前是國內最強在管理系統源碼之一,也是一套完善的云服務器管理系統。阿帕云引擎怎么樣?阿帕云引擎是原zkeys系統,集于:zkeys、星外主機系統、宏杰主機管理系統于三方技術于一身,目前是國內最強在idc管理系統源碼之一,也是一套完善的云服務器管理系統。 ? 阿帕云引擎是一套強大的虛擬化云主機智能管理...
閱讀 1324·2021-11-11 11:00
閱讀 3041·2021-09-24 09:47
閱讀 4949·2021-09-22 15:53
閱讀 960·2021-09-10 10:50
閱讀 3206·2021-09-01 11:40
閱讀 1159·2019-08-30 15:55
閱讀 470·2019-08-30 12:49
閱讀 1048·2019-08-29 17:12