[工控机监控]添加ping命令用于检测设备连通性
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.zhidao.adas.client.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -38,7 +39,8 @@ public class ConnectStatusAdapter extends BaseAdapter<IPCConnectState, ConnectSt
|
||||
@Override
|
||||
protected void onBindDataToItem(ViewHolder viewHolder, IPCConnectState data, int position) {
|
||||
viewHolder.id.setText(String.format(Locale.getDefault(), POS, getItemCount() - position));
|
||||
viewHolder.editText.setText(sdf.format(new Date(data.time)) + "\n" + data.status);
|
||||
String str = "<font color='#999999'>" + sdf.format(new Date(data.time)) + "\n</font> <br />" + data.status;
|
||||
viewHolder.editText.setText(Html.fromHtml(str));
|
||||
viewHolder.editText.setTextColor(mContext.getResources().getColor(data.color));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
@@ -43,6 +44,7 @@ import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import com.google.protobuf.TextFormat;
|
||||
import com.mogo.support.obu.ObuScene;
|
||||
import com.mogo.support.obu.constants.MogoObuConstants;
|
||||
import com.zhidao.adas.client.App;
|
||||
import com.zhidao.adas.client.BuildConfig;
|
||||
import com.zhidao.adas.client.DataDistribution;
|
||||
@@ -79,6 +81,7 @@ import com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS;
|
||||
import com.zhidao.support.adas.high.common.CupidLogUtils;
|
||||
import com.zhidao.support.adas.high.common.ProtocolStatus;
|
||||
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
|
||||
import com.zhidao.support.adas.high.common.RegexUtils;
|
||||
import com.zhjt.mogo.adas.data.bean.AutopilotStatistics;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -139,7 +142,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
|
||||
private RecyclerView infoFragment;
|
||||
private TextView tvConnectState;
|
||||
private ScheduledExecutorService mExecutorServiceConfigTimer;
|
||||
|
||||
private PingFloatWindow pingFloatWindow;
|
||||
|
||||
private final List<String> titleFragmentData = new ArrayList<>();
|
||||
private final List<String> titleBtnData = new ArrayList<>();
|
||||
@@ -291,6 +294,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
|
||||
|
||||
|
||||
private void initView() {
|
||||
ImageView btn_ping = findViewById(R.id.btn_ping);
|
||||
include_title = findViewById(R.id.include_title);
|
||||
etIp = findViewById(R.id.et_ip);
|
||||
background = findViewById(R.id.background);
|
||||
@@ -589,6 +593,67 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
|
||||
} else {
|
||||
background.setVisibility(View.GONE);
|
||||
}
|
||||
btn_ping.setSelected(pingFloatWindow != null);
|
||||
btn_ping.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (pingFloatWindow == null) {
|
||||
Pair<String, Integer> pair = getInputIp();
|
||||
if (pair != null) {
|
||||
pingFloatWindow = new PingFloatWindow(MainActivity.this, pair.first);
|
||||
int[] location = new int[2];
|
||||
btn_ping.getLocationOnScreen(location);
|
||||
int x = location[0];
|
||||
int y = location[1];
|
||||
pingFloatWindow.showFloatWindow(x + (btn_ping.getWidth() / 2) - 260, btn_ping.getY() + btn_ping.getHeight());
|
||||
}
|
||||
|
||||
} else {
|
||||
pingFloatWindow.hideFloatWindow();
|
||||
pingFloatWindow = null;
|
||||
}
|
||||
btn_ping.setSelected(pingFloatWindow != null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private Pair<String, Integer> getInputIp() {
|
||||
String address = etIp.getText().toString().trim();
|
||||
if (TextUtils.isEmpty(address)) {
|
||||
Toast.makeText(this, "请输入OBU地址", Toast.LENGTH_SHORT).show();
|
||||
return null;
|
||||
}
|
||||
String tempIp;
|
||||
int tempPort;
|
||||
if (address.contains(":")) {
|
||||
String[] temp = address.split(":");
|
||||
if (temp.length < 2) {
|
||||
Toast.makeText(this, "地址输入有误", Toast.LENGTH_SHORT).show();
|
||||
return null;
|
||||
}
|
||||
tempIp = temp[0];
|
||||
try {
|
||||
tempPort = Integer.parseInt(temp[1]);
|
||||
if (tempPort <= 0 || tempPort > 65535) {
|
||||
Toast.makeText(this, "端口范围溢出", Toast.LENGTH_SHORT).show();
|
||||
return null;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, "端口不合法", Toast.LENGTH_SHORT).show();
|
||||
return null;
|
||||
}
|
||||
|
||||
} else {
|
||||
tempIp = address;
|
||||
tempPort = MogoObuConstants.DEFAULT_OBU_PORT;
|
||||
}
|
||||
if (!RegexUtils.isIP(tempIp)) {
|
||||
Toast.makeText(this, "地址不合法", Toast.LENGTH_SHORT).show();
|
||||
return null;
|
||||
}
|
||||
return new Pair<>(tempIp, tempPort);
|
||||
}
|
||||
|
||||
private void showListPopupWindow() {
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
package com.zhidao.adas.client.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.mogo.support.obu.common.L;
|
||||
import com.zhidao.adas.client.R;
|
||||
import com.zhidao.adas.client.adapter.ConnectStatusAdapter;
|
||||
import com.zhidao.adas.client.bean.IPCConnectState;
|
||||
import com.zhidao.adas.client.utils.MyLinearLayoutManager;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* ping命令窗口
|
||||
*/
|
||||
public class PingFloatWindow implements View.OnTouchListener {
|
||||
private static final String TAG = PingFloatWindow.class.getSimpleName();
|
||||
private static final int WHAT_STATE = 8;
|
||||
private final Activity mContext;
|
||||
private WindowManager.LayoutParams mWindowParams;
|
||||
private WindowManager mWindowManager;
|
||||
|
||||
private View mFloatLayout;
|
||||
private float mInViewX;
|
||||
private float mInViewY;
|
||||
private float mDownInScreenX;
|
||||
private float mDownInScreenY;
|
||||
private float mInScreenX;
|
||||
private float mInScreenY;
|
||||
private RecyclerView rv_status;
|
||||
private ConnectStatusAdapter adapter;
|
||||
private final List<IPCConnectState> list = new ArrayList<>();
|
||||
private final String ip;
|
||||
private Timer timer;
|
||||
|
||||
public PingFloatWindow(Activity context, String ip) {
|
||||
this.mContext = context;
|
||||
this.ip = ip;
|
||||
initFloatWindow();
|
||||
initHandler();
|
||||
pingTimer(true);
|
||||
}
|
||||
|
||||
private void pingTimer(boolean isStart) {
|
||||
if (isStart) {
|
||||
if (timer == null) {
|
||||
timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
ping();
|
||||
}
|
||||
}, 100L, 2500L);//延时
|
||||
}
|
||||
} else {
|
||||
if (timer != null) {
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ping() {
|
||||
Process p;
|
||||
try {
|
||||
//ping -c 3 -w 100 中 ,-c 是指ping的次数 3是指ping 3次 ,-w 100 以秒为单位指定超时间隔,是指超时时间为100秒
|
||||
p = Runtime.getRuntime().exec("ping -c 1 -w 2 " + ip);
|
||||
int status = p.waitFor();
|
||||
InputStream input = p.getInputStream();
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(input));
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
builder.append(line).append("\n");
|
||||
}
|
||||
String str = "IP:" + ip + " 是否可以连通:" + (status == 0 ? "是" : "否");
|
||||
L.i(TAG, builder.toString() + str);
|
||||
add(str, status == 0);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void add(String str, boolean isConnect) {
|
||||
|
||||
int color;
|
||||
if (isConnect) {
|
||||
color = R.color.connect_status_connected;
|
||||
} else {
|
||||
color = R.color.connect_status_disconnected;
|
||||
}
|
||||
IPCConnectState status = new IPCConnectState(str, color);
|
||||
list.add(0, status);
|
||||
if (list.size() > 100) {
|
||||
list.remove(list.size() - 1);
|
||||
}
|
||||
Message msg = Message.obtain();
|
||||
msg.what = WHAT_STATE;
|
||||
getHandler().sendMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
public void refreshView() {
|
||||
if (adapter != null) {
|
||||
adapter.refreshView();
|
||||
}
|
||||
}
|
||||
|
||||
private void initRV() {
|
||||
//创建默认的线性LayoutManager 横向的GridLayoutManager
|
||||
MyLinearLayoutManager linearLayoutManager = new MyLinearLayoutManager(mContext);
|
||||
// linearLayoutManager.setStackFromEnd(true);//列表再底部开始展示,反转后由上面开始展示
|
||||
// linearLayoutManager.setReverseLayout(true);//列表翻转
|
||||
rv_status.setLayoutManager(linearLayoutManager);
|
||||
//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
|
||||
rv_status.setHasFixedSize(false);
|
||||
rv_status.setNestedScrollingEnabled(false);
|
||||
adapter = new ConnectStatusAdapter();
|
||||
adapter.setHasStableIds(true);
|
||||
rv_status.setAdapter(adapter);
|
||||
adapter.setData(list);
|
||||
}
|
||||
|
||||
private void initFloatWindow() {
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
if (inflater == null)
|
||||
return;
|
||||
mFloatLayout = (View) inflater.inflate(R.layout.layout_float, null);
|
||||
rv_status = mFloatLayout.findViewById(R.id.rv_status);
|
||||
mFloatLayout.setOnTouchListener(this);
|
||||
initRV();
|
||||
mWindowParams = new WindowManager.LayoutParams();
|
||||
// mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
// if (Build.VERSION.SDK_INT >= 26) {//8.0新特性
|
||||
// mWindowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
// }else{
|
||||
// mWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
|
||||
// }
|
||||
|
||||
mWindowManager = mContext.getWindowManager();
|
||||
|
||||
mWindowParams.format = PixelFormat.RGBA_8888;
|
||||
mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
mWindowParams.gravity = Gravity.START | Gravity.TOP;
|
||||
mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
mWindowParams.alpha = 0.9F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
return floatLayoutTouch(motionEvent);
|
||||
}
|
||||
|
||||
private boolean floatLayoutTouch(MotionEvent motionEvent) {
|
||||
switch (motionEvent.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// 获取相对View的坐标,即以此View左上角为原点
|
||||
mInViewX = motionEvent.getX();
|
||||
mInViewY = motionEvent.getY();
|
||||
// 获取相对屏幕的坐标,即以屏幕左上角为原点
|
||||
mDownInScreenX = motionEvent.getRawX();
|
||||
mDownInScreenY = motionEvent.getRawY() - getSysBarHeight(mContext);
|
||||
mInScreenX = motionEvent.getRawX();
|
||||
mInScreenY = motionEvent.getRawY() - getSysBarHeight(mContext);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
// 更新浮动窗口位置参数
|
||||
mInScreenX = motionEvent.getRawX();
|
||||
mInScreenY = motionEvent.getRawY() - getSysBarHeight(mContext);
|
||||
mWindowParams.x = (int) (mInScreenX - mInViewX);
|
||||
mWindowParams.y = (int) (mInScreenY - mInViewY);
|
||||
// 手指移动的时候更新小悬浮窗的位置
|
||||
mWindowManager.updateViewLayout(mFloatLayout, mWindowParams);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
// 如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。
|
||||
if (mDownInScreenX == mInScreenX && mDownInScreenY == mInScreenY) {
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void showFloatWindow(float x, float y) {
|
||||
if (mFloatLayout.getParent() == null) {
|
||||
// DisplayMetrics metrics = new DisplayMetrics();
|
||||
// 默认固定位置,靠屏幕右边缘的中间
|
||||
// mWindowManager.getDefaultDisplay().getMetrics(metrics);
|
||||
mWindowParams.x = (int) x;
|
||||
mWindowParams.y = (int) (y);
|
||||
mWindowManager.addView(mFloatLayout, mWindowParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void hideFloatWindow() {
|
||||
pingTimer(false);
|
||||
if (getHandler() != null) {
|
||||
getHandler().removeCallbacksAndMessages(null);
|
||||
}
|
||||
if (mFloatLayout.getParent() != null)
|
||||
mWindowManager.removeView(mFloatLayout);
|
||||
|
||||
}
|
||||
|
||||
public void setFloatLayoutAlpha(boolean alpha) {
|
||||
if (alpha)
|
||||
mFloatLayout.setAlpha((float) 0.5);
|
||||
else
|
||||
mFloatLayout.setAlpha(1);
|
||||
}
|
||||
|
||||
private int sbar = -1;
|
||||
|
||||
// 获取系统状态栏高度
|
||||
public int getSysBarHeight(Context contex) {
|
||||
if (sbar == -1) {
|
||||
Class<?> c;
|
||||
Object obj;
|
||||
Field field;
|
||||
int x;
|
||||
sbar = 0;
|
||||
try {
|
||||
c = Class.forName("com.android.internal.R$dimen");
|
||||
obj = c.newInstance();
|
||||
field = c.getField("status_bar_height");
|
||||
x = Integer.parseInt(field.get(obj).toString());
|
||||
sbar = contex.getResources().getDimensionPixelSize(x);
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
return sbar;
|
||||
}
|
||||
|
||||
|
||||
private BaseHandler mBaseHandler;
|
||||
|
||||
/**
|
||||
* 初始化一个Handler,如果需要使用Handler,先调用此方法,
|
||||
* 然后可以使用postRunnable(Runnable runnable),
|
||||
* sendMessage在handleMessage(Message msg)中接收msg
|
||||
*/
|
||||
public void initHandler() {
|
||||
mBaseHandler = new BaseHandler(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回Handler,在此之前确定已经调用initHandler()
|
||||
*
|
||||
* @return Handler
|
||||
*/
|
||||
public Handler getHandler() {
|
||||
return mBaseHandler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 同Handler 的 handleMessage,
|
||||
* getHandler.sendMessage,发送的Message在此接收
|
||||
* 在此之前确定已经调用initHandler()
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
protected void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case WHAT_STATE:
|
||||
refreshView();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class BaseHandler extends Handler {
|
||||
private final WeakReference<PingFloatWindow> mObjects;
|
||||
|
||||
public BaseHandler(PingFloatWindow mPresenter) {
|
||||
mObjects = new WeakReference<PingFloatWindow>(mPresenter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
PingFloatWindow mPresenter = mObjects.get();
|
||||
if (mPresenter != null)
|
||||
mPresenter.handleMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
app_ipc_monitoring/src/main/res/drawable/ic_ping.xml
Normal file
12
app_ipc_monitoring/src/main/res/drawable/ic_ping.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M998.4,262.4c0,-38.4 -32,-70.4 -70.4,-70.4H518.4L448,134.4c-6.4,-6.4 -12.8,-6.4 -12.8,-6.4h-320c-51.2,-6.4 -89.6,38.4 -89.6,89.6v569.6c0,64 51.2,108.8 108.8,108.8H672c12.8,0 25.6,-12.8 25.6,-25.6s-12.8,-25.6 -25.6,-25.6H134.4c-32,0 -64,-25.6 -64,-64V217.6c0,-25.6 19.2,-44.8 44.8,-44.8H416l230.4,185.6h307.2v428.8c0,32 -25.6,64 -64,64h-32c-12.8,0 -25.6,12.8 -25.6,25.6s12.8,25.6 25.6,25.6h32c64,0 108.8,-51.2 108.8,-108.8V262.4z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M249.6,460.8h-64v204.8L224,665.6v-83.2h70.4c6.4,0 12.8,-6.4 19.2,-12.8 6.4,0 12.8,-12.8 19.2,-19.2s6.4,-19.2 6.4,-32c0,-19.2 -6.4,-32 -12.8,-38.4 -6.4,-6.4 -12.8,-19.2 -25.6,-19.2h-51.2zM294.4,537.6c0,6.4 -6.4,6.4 -12.8,12.8s-19.2,0 -32,0L224,550.4v-57.6h51.2c6.4,0 12.8,6.4 19.2,6.4v38.4zM371.2,460.8h38.4v204.8h-38.4zM492.8,460.8h-38.4v198.4h38.4v-128l76.8,128h44.8L614.4,460.8L576,460.8v134.4zM838.4,550.4h-89.6v32h44.8L793.6,608c-6.4,6.4 -12.8,6.4 -19.2,12.8 -6.4,6.4 -19.2,6.4 -25.6,6.4 -19.2,0 -32,-6.4 -44.8,-19.2 -12.8,-12.8 -19.2,-32 -19.2,-51.2 0,-19.2 6.4,-38.4 12.8,-51.2 12.8,-12.8 25.6,-19.2 44.8,-19.2 12.8,0 19.2,0 32,6.4 6.4,6.4 12.8,12.8 19.2,25.6l44.8,-6.4c-6.4,-19.2 -12.8,-32 -25.6,-44.8 -12.8,-12.8 -32,-12.8 -57.6,-12.8 -19.2,0 -38.4,6.4 -51.2,12.8 -19.2,6.4 -32,19.2 -38.4,38.4 -6.4,19.2 -12.8,32 -12.8,57.6 0,19.2 6.4,38.4 12.8,51.2 6.4,19.2 19.2,32 38.4,38.4 12.8,6.4 32,12.8 57.6,12.8 19.2,0 32,0 51.2,-6.4s19.2,-19.2 25.6,-25.6v-83.2z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#D81B60"
|
||||
android:pathData="M998.4,262.4c0,-38.4 -32,-70.4 -70.4,-70.4H518.4L448,134.4c-6.4,-6.4 -12.8,-6.4 -12.8,-6.4h-320c-51.2,-6.4 -89.6,38.4 -89.6,89.6v569.6c0,64 51.2,108.8 108.8,108.8H672c12.8,0 25.6,-12.8 25.6,-25.6s-12.8,-25.6 -25.6,-25.6H134.4c-32,0 -64,-25.6 -64,-64V217.6c0,-25.6 19.2,-44.8 44.8,-44.8H416l230.4,185.6h307.2v428.8c0,32 -25.6,64 -64,64h-32c-12.8,0 -25.6,12.8 -25.6,25.6s12.8,25.6 25.6,25.6h32c64,0 108.8,-51.2 108.8,-108.8V262.4z" />
|
||||
<path
|
||||
android:fillColor="#D81B60"
|
||||
android:pathData="M249.6,460.8h-64v204.8L224,665.6v-83.2h70.4c6.4,0 12.8,-6.4 19.2,-12.8 6.4,0 12.8,-12.8 19.2,-19.2s6.4,-19.2 6.4,-32c0,-19.2 -6.4,-32 -12.8,-38.4 -6.4,-6.4 -12.8,-19.2 -25.6,-19.2h-51.2zM294.4,537.6c0,6.4 -6.4,6.4 -12.8,12.8s-19.2,0 -32,0L224,550.4v-57.6h51.2c6.4,0 12.8,6.4 19.2,6.4v38.4zM371.2,460.8h38.4v204.8h-38.4zM492.8,460.8h-38.4v198.4h38.4v-128l76.8,128h44.8L614.4,460.8L576,460.8v134.4zM838.4,550.4h-89.6v32h44.8L793.6,608c-6.4,6.4 -12.8,6.4 -19.2,12.8 -6.4,6.4 -19.2,6.4 -25.6,6.4 -19.2,0 -32,-6.4 -44.8,-19.2 -12.8,-12.8 -19.2,-32 -19.2,-51.2 0,-19.2 6.4,-38.4 12.8,-51.2 12.8,-12.8 25.6,-19.2 44.8,-19.2 12.8,0 19.2,0 32,6.4 6.4,6.4 12.8,12.8 19.2,25.6l44.8,-6.4c-6.4,-19.2 -12.8,-32 -25.6,-44.8 -12.8,-12.8 -32,-12.8 -57.6,-12.8 -19.2,0 -38.4,6.4 -51.2,12.8 -19.2,6.4 -32,19.2 -38.4,38.4 -6.4,19.2 -12.8,32 -12.8,57.6 0,19.2 6.4,38.4 12.8,51.2 6.4,19.2 19.2,32 38.4,38.4 12.8,6.4 32,12.8 57.6,12.8 19.2,0 32,0 51.2,-6.4s19.2,-19.2 25.6,-25.6v-83.2z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_ping_selected" android:state_selected="true" />
|
||||
<item android:drawable="@drawable/ic_ping" />
|
||||
</selector>
|
||||
@@ -17,9 +17,9 @@
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:minWidth="110dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:minWidth="110dp"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/colorWhile"
|
||||
android:textSize="18sp"
|
||||
@@ -288,10 +288,20 @@
|
||||
<ImageView
|
||||
android:id="@+id/btn_router"
|
||||
android:layout_width="40dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="18dp"
|
||||
android:src="@drawable/selector_router" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_ping"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="30dp"
|
||||
android:padding="3dp"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/selector_ping" />
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
</RelativeLayout>
|
||||
Reference in New Issue
Block a user