Android- Textview 在拖动操作时消失
Posted
技术标签:
【中文标题】Android- Textview 在拖动操作时消失【英文标题】:Android- Textview getting disappeared on drag operation 【发布时间】:2019-01-01 18:27:29 【问题描述】:我正在创建一个图像编辑应用程序。我在其中提供了打开相机或画廊以选择图片的便利。选择图片后,用户将导航到其他页面。在显示图片的其他页面中,我使用了一个实现AppCompactImageView
的视图。现在,我提供了使用 edittext 添加文本的便利。单击软键盘的“完成”按钮后,edittext 将消失并被TextView
替换。现在我想将这个 TextView 拖到整个布局中。但是在drop操作之后,它就消失了。下面是我的代码。任何帮助都将不胜感激。
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_
android:layout_
android:background="@android:color/black" >
<ImageButton
android:id="@+id/undoBtn"
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:src="@drawable/undo"/>
<Button
android:id="@+id/clearBtn"
android:layout_
android:layout_
android:text="Clear"
android:layout_toLeftOf="@+id/saveBtn"/>
<Button
android:id="@+id/saveBtn"
android:layout_
android:layout_
android:text="Save"
android:layout_alignParentRight="true"/>
</RelativeLayout>
<RelativeLayout
android:layout_
android:layout_
android:layout_weight="1.8"
android:orientation="vertical"
android:id="@+id/draw_image_linearView">
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_
android:layout_>
<com.example.mobilesolution.imgedit.DrawView
android:id="@+id/frag_home_iv_main"
android:layout_
android:layout_
android:adjustViewBounds="true"
android:scaleType="fitXY"/>
<TextView
android:id="@+id/drawTextView"
android:layout_
android:layout_
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_
android:layout_
android:hint="Enter some text"
android:inputType="textMultiLine"
android:maxLines="3"
android:elevation="10dp"/>
</RelativeLayout>
</RelativeLayout>
<HorizontalScrollView
android:layout_
android:layout_
android:fillViewport="true"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="5dp"
android:scrollbars="none"
android:layout_weight="0.2">
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<LinearLayout
android:layout_
android:layout_
android:gravity="center"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/redBall"
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:onClick="changeColor"
android:src="@drawable/red_ball"
android:tag="red" />
<ImageView
android:id="@+id/blueBall"
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:onClick="changeColor"
android:src="@drawable/blue_ball"
android:tag="blue" />
<ImageView
android:id="@+id/greenBall"
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:onClick="changeColor"
android:src="@drawable/green_ball"
android:tag="green" />
<ImageView
android:id="@+id/yellowBall"
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:onClick="changeColor"
android:src="@drawable/yellow_ball"
android:tag="yellow" />
<ImageView
android:id="@+id/purpleBall"
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:onClick="changeColor"
android:src="@drawable/purple_ball"
android:tag="purple" />
<ImageView
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:src="@drawable/red_ball" />
<ImageView
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:src="@drawable/red_ball" />
<ImageView
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:src="@drawable/red_ball" />
<ImageView
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:src="@drawable/green_ball" />
<ImageView
android:layout_
android:layout_
android:layout_marginRight="10dp"
android:src="@drawable/green_ball" />
</LinearLayout>
</LinearLayout>
</HorizontalScrollView>
<RelativeLayout
android:id="@+id/brushBtnLayout"
android:layout_
android:layout_
android:background="@android:color/black">
<ImageView
android:id="@+id/imageBrush"
android:layout_
android:layout_
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_
android:layout_
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>
【问题讨论】:
【参考方案1】:您应该在存在拖动时设置X
和Y
坐标,而不是设置边距。
再次更新 放置视图是您的文本视图应该放入的位置。这应该保持拖动侦听器
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;
);
【讨论】:
让我试一次 对不起,它对我不起作用。现在我无法拖动视图。 您正在做错误的拖放操作。不得在也被拖动的视图上设置拖动侦听器。我已经更新了答案 调用OnDragListener
的视图和调用startDrag
的视图不能相同
真的很抱歉,我没听清楚。可以用代码解释一下吗?【参考方案2】:
您正在为初学者在同一个视图上拖动和设置拖动监听器,通常拖动监听器是另一个视图,而不是被移动的视图来监听被拖动的视图,以防它在它上面或进入它或退出,等等。 这是我认为你应该做的:
编辑 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:我在更改代码的 cmets 中添加了 TODO。
【讨论】:
嗨 Mr.O... 非常感谢您的帮助.. 我尝试了您的代码.. 现在它并没有消失.. 但对于初始拖动它移动到最左边的角落.. 后记无法拖动..它卡在同一个位置... 您还添加了case DragEvent.ACTION_DRAG_ENDED:
下的编辑部分addedTxtView.setVisibility(View.VISIBLE);
?
所以现在发生的情况是,当您长按文本视图时,阴影会出现并随手指移动,但是当您移开手指时,它会完全消失,您必须重新创建文本视图的活动以再次出现?
好的,我再次对代码的两个部分进行了更改。我将 TODO 放在 cmets 中。我不知道活动的根视图组布局是什么,但我假设是相对布局,您需要在我编写待办事项的地方为其设置 id。如果它不是相对布局,您需要将一些变量从相对布局更改为它是什么。感谢您的耐心等待,请再试一次?
很抱歉需要再次快速编辑。编辑位于case DragEvent.ACTION_DRAG_ENDED:
下的部分以上是关于Android- Textview 在拖动操作时消失的主要内容,如果未能解决你的问题,请参考以下文章
请问android编程中,textview里面放了很多文字,怎样拖动textview让下面的内容显示出来。