Androidカスタム編集可能フルスクリーンドラッグ可能EditText

47999 ワード

前言開発では、EditTextをドラッグして編集する必要があります.フォーカスを失ったとき、TextViewになります.フォーカスを取得したとき、編集することができます.多くの資料を調べて、最終的に完成します.開発時間がきついので、メモを1つだけします.
効果図:1.カスタムビュー
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);
    }
}