一.带删除的edittext
package com.example.esp8266.activity.utile;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import com.example.esp8266.R;
/**
* @Author lgd
* @Date 2023/3/23 14:02
*/
public class DeleteContentEditText extends androidx.appcompat.widget.AppCompatEditText {
private Context mContext;
private Drawable deleteImg;
public DeleteContentEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
init(attrs);
}
public DeleteContentEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
init(attrs);
}
private void init(AttributeSet attrs) {
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.DeleteContent_Edit);
deleteImg = typedArray.getDrawable(R.styleable.DeleteContent_Edit_deleteImg);
typedArray.recycle();
if (deleteImg != null){//判断是否添加了删除按钮
addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
setDeleteImg();
}
@Override
public void afterTextChanged(Editable editable) {
}
});
}
}
private void setDeleteImg() { //设置删除按钮,输入字符串大于1时显示
if (length()< 1){
setCompoundDrawablesWithIntrinsicBounds(null,null,null,null);
}else {
setCompoundDrawablesWithIntrinsicBounds(null,null,deleteImg,null);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (deleteImg != null && event.getAction() == MotionEvent.ACTION_UP){//对内容清空
getText().clear();
}
return super.onTouchEvent(event);
}
}
使用:
<com.example.esp8266.activity.utile.DeleteContentEditText android:id="@+id/logScan_et" android:layout_width="wrap_content" android:layout_height="40dp" android:layout_weight="5" app:deleteImg="@drawable/delete_ico" android:background="@null" android:gravity="center" android:hint="@string/inputContent" android:textColor="@color/black"/>
二. 定位工具类
package com.example.esp8266.activity.utile;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import java.util.List;
public class LocationUtils {
private volatile static LocationUtils uniqueInstance;
private LocationManager locationManager;
private String locationProvider;
private Location location;
private Context mContext;
private LocationUtils(Context context) {
mContext = context;
getLocation();
}
//采用Double CheckLock(DCL)实现单例
public static LocationUtils getInstance(Context context) {
if (uniqueInstance == null) {
synchronized (LocationUtils.class) {
if (uniqueInstance == null) {
uniqueInstance = new LocationUtils( context );
}
}
}
return uniqueInstance;
}
private void getLocation() {
//1.获取位置管理器
locationManager = (LocationManager) mContext.getSystemService( Context.LOCATION_SERVICE );
//2.获取位置提供器,GPS或是NetWork
List<String> providers = locationManager.getProviders( true );
if (providers.contains( LocationManager.NETWORK_PROVIDER )) {
//网络定位
System.out.println("网络定位");
locationProvider = LocationManager.NETWORK_PROVIDER;
} else if (providers.contains( LocationManager.GPS_PROVIDER )) {
//GPS定位
System.out.println("GPS定位");
locationProvider = LocationManager.GPS_PROVIDER;
} else {
System.out.println("没有可用的位置提供器");
return;
}
// 需要检查权限,否则编译报错,想抽取成方法都不行,还是会报错。只能这样重复 code 了。
if (Build.VERSION.SDK_INT >= 23 &&
ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
return;
}
//3.获取上次的位置,一般第一次运行,此值为null
Location location = locationManager.getLastKnownLocation( locationProvider );
if (location != null) {
setLocation( location );
}
// 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace
locationManager.requestLocationUpdates( locationProvider, 0, 0, locationListener );
}
private void setLocation(Location location) {
this.location = location;
String address = "纬度:" + location.getLatitude() + "经度:" + location.getLongitude();
// Log.d( TAG, );
// System.out.println(address+"99999999999999999");
}
//获取经纬度
public Location showLocation() {
return location;
}
// 移除定位监听
public void removeLocationUpdatesListener() {
// 需要检查权限,否则编译不过
if (Build.VERSION.SDK_INT >= 23 &&
ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (locationManager != null) {
uniqueInstance = null;
locationManager.removeUpdates( locationListener );
}
}
/**
* LocationListern监听器
* 参数:地理位置提供器、监听位置变化的时间间隔、位置变化的距离间隔、LocationListener监听器
*/
LocationListener locationListener = new LocationListener() {
/**
* 当某个位置提供者的状态发生改变时
*/
@Override
public void onStatusChanged(String provider, int status, Bundle arg2) {
}
/**
* 某个设备打开时
*/
@Override
public void onProviderEnabled(String provider) {
}
/**
* 某个设备关闭时
*/
@Override
public void onProviderDisabled(String provider) {
}
/**
* 手机位置发生变动
*/
@Override
public void onLocationChanged(Location location) {
location.getAccuracy();//精确度
setLocation( location );
}
};
}
使用:
Location location = LocationUtils.getInstance(getActivity() ).showLocation(); String address = "纬度:" + location.getLatitude() + "经度:" + location.getLongitude();
三.长按事件 (可设置长按时间)
package com.example.esp8266.activity.utile;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
/**
* @Author lgd
* @Date 2024/5/7 9:34
*/
public class LongClickUtils {
private static final String TAG = "LongClickUtils";
/**
* @param handler 外界handler(为了减少handler的泛滥使用,最好全局传handler引用,如果没有就直接传 new Handler())
* @param longClickView 被长按的视图(任意控件)
* @param delayMillis 长按时间,毫秒
* @param longClickListener 长按回调的返回事件
*/
public static void setLongClick(final Handler handler, final View longClickView, final long delayMillis, final View.OnLongClickListener longClickListener) {
longClickView.setOnTouchListener(new View.OnTouchListener() {
private int TOUCH_MAX = 50;
private int mLastMotionX;
private int mLastMotionY;
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
// 抬起时,移除已有Runnable回调,抬起就算长按了(不需要考虑用户是否长按了超过预设的时间)
handler.removeCallbacks(r);
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(mLastMotionX - x) > TOUCH_MAX
|| Math.abs(mLastMotionY - y) > TOUCH_MAX) {
// 移动误差阈值
// xy方向判断
// 移动超过阈值,则表示移动了,就不是长按(看需求),移除 已有的Runnable回调
handler.removeCallbacks(r);
}
break;
case MotionEvent.ACTION_DOWN:
// 每次按下重新计时
// 按下前,先移除 已有的Runnable回调,防止用户多次单击导致多次回调长按事件的bug
handler.removeCallbacks(r);
mLastMotionX = x;
mLastMotionY = y;
// 按下时,开始计时
handler.postDelayed(r, delayMillis);
break;
}
return true;//onclick等其他事件不能用请改这里
}
private Runnable r = new Runnable() {
@Override
public void run() {
if (longClickListener != null) {// 回调给用户,用户可能传null,需要判断null
longClickListener.onLongClick(longClickView);
}
}
};
});
}
}
使用:
LongClickUtils.setLongClick(new Handler(), XXXView, 2000, new View.OnLongClickListener() { <