前言 在开发中,有一种需求,需要一种EditText可拖动并且可编辑,在失去焦点时,变成TextView,获取焦点时,可编辑,查阅好多资料,最终完成,由于开发时间比较紧,只做个笔记
效果图: 1.自定义View
import android.content.Context; import android.graphics.Paint; import android.text.Editable; import android.text.TextPaint; import android.text.TextWatcher; import android.util.AttributeSet; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.EditText; import android.widget.LinearLayout; import com.xinrui.guestservice.R; import com.xinrui.guestservice.utils.ToolUtils; public class DragLayout extends LinearLayout { private int lastX, lastY; private int parentWidth, parentHeight; private DragEditText mEditText; private Context mContext; private View mTypefaceView; private LayoutInflater inflater; private ToolUtils mToolUtils; public DragLayout(Context context) { this(context, null); } public DragLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DragLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mContext=context; mToolUtils = ToolUtils.getInstance(mContext); inflater = LayoutInflater.from(context); init(); } private void init() { setEditTextAttr(20,"请输入内容"); } public int dptopx( float dpValue){ final float scale = mContext.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } public void setEditTextAttr(int textsize,String text){ mTypefaceView=inflater.inflate(R.layout.edt_layout,null); int height = dptopx((float)((textsize + 0.00000007)/0.7535))+textsize; mEditText = new DragEditText(getContext()); Paint mTextPaint = mEditText.getPaint(); mTextPaint.setTextSize(textsize); int width = dptopx(mTextPaint.measureText(text))+textsize; //初始化控件的布局 if(mToolUtils.isScreenOriatationPortrait()) { setX((1080 - width) / 2); setY((1920 - height) / 2); }else{ setX((1920 - width) / 2); setY((1080 - height) / 2); } LinearLayout.LayoutParams mEdtlayoutParams = new LinearLayout.LayoutParams(width,LayoutParams.WRAP_CONTENT); mEditText.setLayoutParams(mEdtlayoutParams); int padding = textsize/10; mEditText.setPadding(-padding,-padding,-padding,-padding); mEditText.setText(text); mEditText.setGravity(Gravity.LEFT|Gravity.CENTER_VERTICAL); mEditText.setTextSize(textsize); mEditText.setTextColor(getContext().getResources().getColor(R.color.colorWhite)); mEditText.setBackground(null); addView(mEditText); LinearLayout.LayoutParams mViewlayoutParams = new LinearLayout.LayoutParams(width, 55); mViewlayoutParams.topMargin=5; mTypefaceView.setLayoutParams(mViewlayoutParams); mEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { String value = s.toString().trim(); TextPaint mTextPaint = mEditText.getPaint(); mTextPaint.setTextSize(mEditText.getTextSize()); int mTextViewWidth = (int) mTextPaint.measureText(value); int width = mEditText.getWidth(); if (mTextViewWidth > width) { LinearLayout.LayoutParams mEdtlayoutParams = new LinearLayout.LayoutParams(mTextViewWidth, LayoutParams.WRAP_CONTENT); mEditText.setLayoutParams(mEdtlayoutParams); LinearLayout.LayoutParams mViewlayoutParams = new LinearLayout.LayoutParams(mTextViewWidth, 55); mViewlayoutParams.topMargin=5; mTypefaceView.setLayoutParams(mViewlayoutParams); DragLayout.this.invalidate(); } } }); mEditText.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if(hasFocus){ mEditText.setBackgroundResource(R.drawable.edit_bg); addView(mTypefaceView); }else{ mEditText.setBackground(null); removeView(mTypefaceView); } } }); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { lastX = (int) ev.getRawX(); lastY = (int) ev.getRawY(); return false; }else if(ev.getAction()==MotionEvent.ACTION_UP){ return false; } return true; } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: int deltaX = (int) event.getRawX() - lastX; int deltaY = (int) event.getRawY() - lastY; if (parentWidth == 0) { ViewGroup mViewGroup = (ViewGroup) getParent(); parentWidth = mViewGroup.getWidth(); parentHeight = mViewGroup.getHeight(); } if (getTranslationX() < -getLeft() && deltaX < 0) deltaX = 0; else if (getTranslationX() > (parentWidth - getRight()) && deltaX > 0) deltaX = 0; if (getTranslationY() < -getTop() && deltaY < 0) deltaY = 0; else if (getTranslationY() > (parentHeight - getBottom()) && deltaY > 0) deltaY = 0; setTranslationX(getTranslationX() + deltaX); setTranslationY(getTranslationY() + deltaY); lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); break; case MotionEvent.ACTION_UP: break; } return true; } private static class DragEditText extends EditText{ private int downX, downY; public DragEditText(Context context) { super(context); } public DragEditText(Context context, AttributeSet attrs) { super(context, attrs); } public DragEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean dispatchTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = (int) event.getRawX(); downY = (int) event.getRawY(); getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: int upX = (int) event.getRawX() - downX; int upY = (int) event.getRawY() - downY; if (Math.abs(upX) <= ViewConfiguration.get(getContext()).getScaledTouchSlop() && Math.abs(upY) <= ViewConfiguration.get(getContext()).getScaledTouchSlop()) { getParent().requestDisallowInterceptTouchEvent(true); } else { getParent().requestDisallowInterceptTouchEvent(false); } break; } return super.dispatchTouchEvent(event); } @Override protected void onSelectionChanged(int selStart, int selEnd) { super.onSelectionChanged(selStart, selEnd); //保证光标始终在最后面 if (selStart == selEnd) {//防止不能多选 setSelection(getText().length()); } } } }2.Activity 部分代码
import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.MotionEvent; import android.view.inputmethod.InputMethodManager; import android.widget.RelativeLayout; import com.xinrui.guestservice.view.DragLayout; public class DisplayActivity extends Activity { private DragLayout mDragLayout; private RelativeLayout main_area; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.display_layout); init(); } private void init(){ main_area = (RelativeLayout)findViewById(R.id.main_area); mDragLayout=(DragLayout)findViewById(R.id.drag_area); int imageid = getIntent().getIntExtra("image", -1); if (imageid != -1) { main_area.setBackgroundResource(imageid); } else { String imagepath = getIntent().getStringExtra("imagepath"); Bitmap bitmap = BitmapFactory.decodeFile(imagepath); Drawable drawable = new BitmapDrawable(bitmap); main_area.setBackground(drawable); } } @Override public boolean onTouchEvent(MotionEvent event) { //EditText失去焦点时,隐藏输入法 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (event.getAction() == MotionEvent.ACTION_DOWN) { if (getCurrentFocus() != null) { if (getCurrentFocus().getWindowToken() != null) { imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); mDragLayout.clearFocus(); } } } return super.onTouchEvent(event); } }3.display_layout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_area" android:focusableInTouchMode="true" android:layout_width="match_parent" android:layout_height="match_parent"> <com.xinrui.guestservice.view.DragLayout android:id="@+id/drag_area" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> </com.xinrui.guestservice.view.DragLayout> </RelativeLayout>4.ToolUtils类
import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Paint; import android.graphics.Rect; import android.util.Log; import android.view.View; import android.widget.Toast; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.xinrui.guestservice.R; import com.xinrui.guestservice.entity.PictureInfo; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; public class ToolUtils { private static ToolUtils toolUtils; private Context mContext; private ArrayList<String> paint_list = null; private ArrayList<PictureInfo> fileItemList; private ToolUtils(Context context) { mContext = context.getApplicationContext(); paint_list = new ArrayList<>(); fileItemList = new ArrayList<>(); } public static ToolUtils getInstance(Context context) { if (toolUtils == null) { toolUtils = new ToolUtils(context); } return toolUtils; } public boolean isScreenOriatationPortrait() { return mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; } public int dptopx( float dpValue){ final float scale = mContext.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } }