Android-拖动操作时TextView消失了

10

我正在创建一个图像编辑应用程序。其中我提供了打开相机或画廊选择图片的功能。在选择图片后,用户将导航到其他页面。在另一个页面上,为了显示图片,我使用了一个实现了AppCompactImageView的视图。现在,在它上面,我提供了使用edittext添加文本的功能。点击软键盘的“完成”按钮后,edittext将消失,并被TextView替换。现在我想将这个TextView拖动到整个布局中。但是拖放操作之后,它会消失。以下是我的代码。任何帮助都将不胜感激。

  1. DrawActivity.java

    public class DrawActivity extends AppCompatActivity {

DrawView imgView;
Button resetBtn, saveBtn;
ImageButton undoBtn;
Bundle extras;
Context context;
EditText addTxtBox;
ImageView brushImg, fontImg;
TextView addedTxtView;
// LinearLayout mainLinear;
RelativeLayout mainRelative;
public int rowX, rowY;
public String txtVal;
private android.widget.RelativeLayout.LayoutParams layoutParams;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getSupportActionBar().hide();
    setContentView(R.layout.activity_draw);

    context = this.getApplicationContext();

    mainRelative = (RelativeLayout) findViewById(R.id.relativeLayout1);
    imgView = (DrawView) findViewById(R.id.frag_home_iv_main);
    resetBtn = (Button) findViewById(R.id.clearBtn);
    undoBtn = (ImageButton) findViewById(R.id.undoBtn);
    saveBtn = (Button) findViewById(R.id.saveBtn);
    addTxtBox = (EditText) findViewById(R.id.addTxt);
    brushImg = (ImageView) findViewById(R.id.imageBrush);
    fontImg = (ImageView) findViewById(R.id.imageFont);

    addedTxtView = (TextView) findViewById(R.id.drawTextView);
    addedTxtView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());
            String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};

            ClipData dragData = new ClipData(v.getTag().toString(),mimeTypes, item);
            View.DragShadowBuilder myShadow = new View.DragShadowBuilder(addedTxtView);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                Log.d("Vishal sdk","in if");
                v.startDragAndDrop(dragData, myShadow, null, 0);
            } else {
                Log.d("Vishal sdk","in else");
                v.startDrag(dragData, myShadow, null, 0);
            }
            return false;
        }
    });


    addedTxtView.setOnDragListener(new View.OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            Log.d("Vishal check", String.valueOf(event.getAction()));
            switch(event.getAction()) {
                case DragEvent.ACTION_DRAG_STARTED:
                    layoutParams = (RelativeLayout.LayoutParams)v.getLayoutParams();
                    Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_STARTED");
                    return true;
                    // Do nothing

                case DragEvent.ACTION_DRAG_ENTERED:
                    Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_ENTERED");
                    int x_cord = (int) event.getX();
                    int y_cord = (int) event.getY();
                    return true;

                case DragEvent.ACTION_DRAG_EXITED :
                    Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_EXITED");
                    x_cord = (int) event.getX();
                    y_cord = (int) event.getY();
                    layoutParams.leftMargin = x_cord;
                    layoutParams.topMargin = y_cord;
                    v.setLayoutParams(layoutParams);
                    v.setVisibility(View.VISIBLE);
                    // view.setVisibility(View.VISIBLE);
                    return true;

                case DragEvent.ACTION_DRAG_LOCATION  :
                    Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_LOCATION");
                    x_cord = (int) event.getX();
                    y_cord = (int) event.getY();
                    return true;

                case DragEvent.ACTION_DRAG_ENDED   :
                    Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_ENDED");
                    return true;
                    // Do nothing

                case DragEvent.ACTION_DROP:
                    Log.d("Vishal Drag", "ACTION_DROP event");
                   /* x_cord = (int) event.getX();
                    y_cord = (int) event.getY();
                    View view = (View) event.getLocalState();
                    view.setX(x_cord - (view.getWidth() / 2));
                    view.setY(y_cord - (view.getWidth() / 2));
                    view.setVisibility(View.VISIBLE);*/

                    return true;
                    // Do nothing
                default:
                    return true;

            }
            //return true;
        }
    });


    addTxtBox.setImeOptions(EditorInfo.IME_ACTION_DONE);
    addTxtBox.setRawInputType(InputType.TYPE_CLASS_TEXT);

    addTxtBox.setVisibility(View.GONE);
    // addedTxtView.setVisibility(View.GONE);


    extras = getIntent().getExtras();
    imgView.setImageURI(Uri.parse(extras.getString("selectedImg")));

    imgView.setDrawingCacheEnabled(true);

    brushImg.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            imgView.setBrushActive(true);
        }
    });

    fontImg.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            imgView.setBrushActive(false);
            addTxtBox.setVisibility(View.VISIBLE);
            addTxtBox.requestFocus();
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY);
        }
    });

    addTxtBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                Toast.makeText(DrawActivity.this, addTxtBox.getText(), Toast.LENGTH_SHORT).show();
                addedTxtView.setVisibility(View.VISIBLE);
                txtVal = addTxtBox.getText().toString();
                imgView.getTxtValue(addTxtBox.getText().toString());
                addedTxtView.setText(addTxtBox.getText().toString());
                addedTxtView.setTag(addTxtBox.getText().toString());
                addTxtBox.setVisibility(View.GONE);
                try {
                    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
                    inputMethodManager.hideSoftInputFromWindow(addTxtBox.getWindowToken(), InputMethodManager.RESULT_UNCHANGED_SHOWN);
                }catch (Exception e){
                    e.printStackTrace();
                }
                return true;
            }
            return false;
        }
    });


    resetBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            imgView.resetPaths();
        }
    });

    undoBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            imgView.removeLastPath();
        }
    });

    saveBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bitmap bitmap = imgView.getDrawingCache();
            File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            path.mkdirs();
            Long tsLong = System.currentTimeMillis()/1000;
            String ts = tsLong.toString();
            File imageFile = new File(path, ts+".png"); // Imagename.png

            try{
                FileOutputStream out = new FileOutputStream(imageFile);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // Compress Image
                try {
                    out.flush();
                    out.close();
                } catch (IOException e){
                    e.printStackTrace();
                }


                // Tell the media scanner about the new file so that it is
                // immediately available to the user.
                MediaScannerConnection.scanFile(context,new String[] { imageFile.getAbsolutePath() }, null,new MediaScannerConnection.OnScanCompletedListener() {
                    public void onScanCompleted(String path, Uri uri) {
                        Log.i("ExternalStorage", "Scanned " + path + ":");
                        Log.i("ExternalStorage", "-> uri=" + uri);

                    }
                });
                Toast.makeText(context,"Saved", Toast.LENGTH_SHORT).show();

                Intent intent = new Intent(DrawActivity.this, MainActivity.class);
                startActivity(intent);
            } catch(FileNotFoundException e) {
                Toast.makeText(context,"Error" + e.toString(), Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
        }
    });

}



public void redrawImage() {
    Bitmap bm = imgView.getDrawingCache();
    Bitmap proxy = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(proxy);
    Paint paint = new Paint();
    // paint.setStyle(Paint.Style.STROKE);
    paint.setColor(Color.RED);
    paint.setTextSize(100);
    paint.setAntiAlias(true);

    c.drawBitmap(bm, new Matrix(), paint);
    c.drawText(txtVal, imgView.getWidth()+rowX, imgView.getHeight()+rowY, paint);
    imgView.setImageBitmap(proxy);
}

public void changeColor(View view) {
    Log.d("Vishal selected color", view.getTag().toString());

    switch (view.getTag().toString()){
        case "red":
            imgView.setBrushColor(Color.RED);
            break;

        case "blue":
            imgView.setBrushColor(Color.BLUE);
            break;

        case "green" :
            imgView.setBrushColor(Color.GREEN);
            break;

        case "yellow":
            imgView.setBrushColor(Color.YELLOW);
            break;

        case "purple":
            imgView.setBrushColor(getResources().getColor(R.color.purple));
            break;

        default:
            imgView.setBrushColor(Color.BLACK);
    }
    //
}

  • activity_draw.xml

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/black" >
    
        <ImageButton
            android:id="@+id/undoBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:src="@drawable/undo"/>
    
        <Button
            android:id="@+id/clearBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clear"
            android:layout_toLeftOf="@+id/saveBtn"/>
    
        <Button
            android:id="@+id/saveBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Save"
            android:layout_alignParentRight="true"/>
    
    </RelativeLayout>
    
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1.8"
        android:orientation="vertical"
        android:id="@+id/draw_image_linearView">
    
        <RelativeLayout
            android:id="@+id/relativeLayout1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <com.example.mobilesolution.imgedit.DrawView
                android:id="@+id/frag_home_iv_main"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:adjustViewBounds="true"
                android:scaleType="fitXY"/>
    
            <TextView
                android:id="@+id/drawTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:elevation="100dp"
                android:layout_centerInParent="true"
                android:textColor="@android:color/black"
                android:textSize="16dp"
                />
    
            <EditText
                android:id="@+id/addTxt"
                android:layout_centerInParent="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:hint="Enter some text"
                android:inputType="textMultiLine"
                android:maxLines="3"
                android:elevation="10dp"/>
    
    
        </RelativeLayout>
    
    </RelativeLayout>
    
    <HorizontalScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fillViewport="true"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:paddingTop="5dp"
        android:scrollbars="none"
        android:layout_weight="0.2">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <LinearLayout
                android:layout_width="447dp"
                android:layout_height="match_parent"
                android:gravity="center"
                android:orientation="horizontal"
                android:padding="10dp">
    
                <ImageView
                    android:id="@+id/redBall"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:onClick="changeColor"
                    android:src="@drawable/red_ball"
                    android:tag="red" />
    
                <ImageView
                    android:id="@+id/blueBall"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:onClick="changeColor"
                    android:src="@drawable/blue_ball"
                    android:tag="blue" />
    
                <ImageView
                    android:id="@+id/greenBall"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:onClick="changeColor"
                    android:src="@drawable/green_ball"
                    android:tag="green" />
    
                <ImageView
                    android:id="@+id/yellowBall"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:onClick="changeColor"
                    android:src="@drawable/yellow_ball"
                    android:tag="yellow" />
    
                <ImageView
                    android:id="@+id/purpleBall"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:onClick="changeColor"
                    android:src="@drawable/purple_ball"
                    android:tag="purple" />
    
                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:src="@drawable/red_ball" />
    
                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:src="@drawable/red_ball" />
    
                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:src="@drawable/red_ball" />
    
                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:src="@drawable/green_ball" />
    
                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:src="@drawable/green_ball" />
    
            </LinearLayout>
        </LinearLayout>
    
    
    </HorizontalScrollView>
    
    
    <RelativeLayout
        android:id="@+id/brushBtnLayout"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:background="@android:color/black">
    
        <ImageView
            android:id="@+id/imageBrush"
            android:layout_width="65dp"
            android:layout_height="37dp"
            android:layout_marginLeft="66dp"
            android:layout_marginStart="66dp"
            android:background="@android:color/white"
            android:src="@drawable/brush"
            android:layout_alignTop="@+id/imageFont"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true" />
    
        <ImageView
            android:id="@+id/imageFont"
            android:layout_width="65dp"
            android:layout_height="37dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginEnd="52dp"
            android:layout_marginRight="52dp"
            android:background="@android:color/white"
            android:src="@drawable/font" />
    
    </RelativeLayout>
    

  • 2个回答

    2

    在拖动结束时,应该设置XY坐标,而不是设置边距。

    再次更新 放置视图是您的文本视图应该放置的位置。这应该包含拖动侦听器。

    frag_home_iv_main.setOnDragListener(new View.OnDragListener() {
                @Override
                public boolean onDrag(View view, DragEvent dragEvent) {
                    int action = dragEvent.getAction();
                    View viewdrag = (View) dragEvent.getLocalState();
                    if(action == DragEvent.ACTION_DRAG_ENTERED){
                        //do something
                    }
                    else if(action == DragEvent.ACTION_DRAG_EXITED){
                        //do something
    
                        Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_EXITED");
                        x_cord = (int) event.getX();
                        y_cord = (int) event.getY();
                        viewdrag .setY(y_cord);
                        viewdrag .setX(x_cord);
                    }
    
                    else if(action == DragEvent.ACTION_DROP){
                        //do something
                    }
                    return true;
                }
            });
    

    抱歉,它对我没有起作用。现在我无法拖动视图。 - Flutterian
    你的拖放操作有误。拖放监听器不能设置在正在被拖动的视图上。我已经更新了我的答案。 - Niza Siwale
    非常抱歉,我没有完全理解您的意思。您能否用代码来解释一下? - Flutterian
    我已经更新了答案。你想把“TextView”拖到哪里?也就是说,哪个视图应该等待放置。 - Niza Siwale
    让我们在聊天中继续这个讨论 - Niza Siwale
    显示剩余6条评论

    2
    首先,你正在拖动并设置拖动监听器在同一个视图上,通常拖动监听器是另一个视图而不是被移动的视图,以便监听被拖动的视图的移动情况,例如是否悬停在其上方、进入或退出等。我认为你应该这样做:
    //TODO change the view that listens to the drag event to root view layout
    RelativeLayout layout = findViewById(R.id.yourRootViewLayout) //Change this to your root layout
    layout.setOnDragListener(new View.OnDragListener() {
       //I changed the view that listens to the dragging, 
      //not sure if that's the one you prefer but you can choose your own 
     //to listen to these events if it overlaps or not, etc.
            @Override
            public boolean onDrag(View v, DragEvent event) {
                Log.d("Vishal check", String.valueOf(event.getAction()));
                switch(event.getAction()) {
                    case DragEvent.ACTION_DRAG_STARTED:
                        layoutParams = (RelativeLayout.LayoutParams)v.getLayoutParams();
                        Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_STARTED");
                        return true;
                        // Do nothing
    
                    case DragEvent.ACTION_DRAG_ENTERED:
                        Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_ENTERED");
                        int x_cord = (int) event.getX();
                        int y_cord = (int) event.getY();
                        return true;
    
                    case DragEvent.ACTION_DRAG_EXITED :
                        Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_EXITED");
                        // view.setVisibility(View.VISIBLE);
                        return true;
    
                    case DragEvent.ACTION_DRAG_LOCATION  :
                        Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_LOCATION");
                        x_cord = (int) event.getX();
                        y_cord = (int) event.getY();
                        return true;
    
              //I put the code that you had in exited in ended because that's what 
              //listens to when  the drag stops no matter where it is
                    case DragEvent.ACTION_DRAG_ENDED   :
                        Log.d("Vishal Drag", "Action is DragEvent.ACTION_DRAG_ENDED");
                        x_cord = (int) event.getX();
                        y_cord = (int) event.getY();
                        //TODO change the code below
                        View newView = (View) event.getLocalState();
                        ViewGroup owner = (ViewGroup) newView.getParent();
                        owner.removeView(newView);
                        RelativeLayout container = (RelativeLayout) v;
                        container.addView(newView);
                        newView.setVisibility(View.VISIBLE);
                        newView.setX(x_cord);
                        newView.setY(y_cord);
                        return true;
    
                    case DragEvent.ACTION_DROP:
                        Log.d("Vishal Drag", "ACTION_DROP event");
                       /* x_cord = (int) event.getX();
                        y_cord = (int) event.getY();
                        View view = (View) event.getLocalState();
                        view.setX(x_cord - (view.getWidth() / 2));
                        view.setY(y_cord - (view.getWidth() / 2));
                        view.setVisibility(View.VISIBLE);*/
    
                        return true;
                        // Do nothing
                    default:
                        return true;
    
                }
                //return true;
            }
        });
    

    如果有更多的问题,请告诉我发生了什么,我很乐意提供帮助。

    addedTxtView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());
                String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};
            ClipData dragData = new ClipData(v.getTag().toString(),mimeTypes, item);
            //I changed addedTxtView to the current view being clicked
            View.DragShadowBuilder myShadow = new View.DragShadowBuilder(v);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                Log.d("Vishal sdk","in if");
                //TODO Edit added v instead of null
                v.startDragAndDrop(dragData, myShadow, v, 0);
            } else {
                Log.d("Vishal sdk","in else");
                //TODO Edit added v instead of null
                v.startDrag(dragData, myShadow, v, 0);
            }
            //Let addedTxtView be invisible so there aren't two views at the same time
            addedTxtView.setVisibility(View.INVISIBLE);
            return false;
        }
    });
    

    我还编辑了上部分代码:在拖动事件ACTION_DRAG_ENDED结束后,我使添加的文本视图addedTxtView再次可见。

    编辑2:我在更改代码的注释中添加了TODO。


    嗨,O先生...非常感谢您的帮助...我尝试了您的代码...现在它不会消失了...但是对于初始拖动,它会移动到最左边的角落...之后就无法拖动了...它卡在同一位置... - Flutterian
    您是否也在 case DragEvent.ACTION_DRAG_ENDED: 下添加了编辑后的部分,即 addedTxtView.setVisibility(View.VISIBLE); - Mr.O
    现在发生的是,当您长按文本视图时,阴影会出现并随着手指移动,但当您松开手指时,它会完全消失,您必须重新创建文本视图的活动才能再次出现? - Mr.O
    好的,我又对代码的两个部分进行了更改。我在注释中放置了TODOs。我不知道你的活动的根视图组布局是什么,但我假设它是相对布局,在我写TODO的地方需要设置其ID。如果它不是相对布局,则需要将一些变量从相对布局更改为其他类型。感谢您的耐心等待,请再试一次? - Mr.O
    抱歉,需要再快速编辑一下。编辑内容在case DragEvent.ACTION_DRAG_ENDED:部分下面。 - Mr.O
    让我们在聊天中继续这个讨论。点击此处进入聊天室 - Mr.O

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接