Reputation: 554
I have relative layout which consists of a button
When I press this button it adds the new custom edittext that I have created to the relative layout
These custom edit text can be dragged and dropped anywhere in the layout. This part of the code works fine.
The problem is :: When I add the first custom edit text and reposition it by dragging it and adding another custom edittext the app works weird not as expected( the two custom edittext overlap each other).
For a better understanding of my problem watch this video
Instead of custom edit text I have tried the same code with textviews and its working fine you can watch this video for the textviews samplehere
Maybe it's due to the setting of on long click listener to my custom edit text in the onclick listener of the button
my main activity
public class MainActivity extends Activity
{
TextView X, Y;
RelativeLayout dropLayout;
LayoutParams params;
Button addText;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dropLayout = (RelativeLayout) findViewById(R.id.ondraglayout);
dropLayout.setOnDragListener(new MyDragListener());
addText = (Button) findViewById(R.id.mainButton1);
addText.setOnClickListener(new MyButtonClickListener());
X=(TextView) findViewById(R.id.xvalue);
Y=(TextView) findViewById(R.id.yvalue);
dropLayout.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View p1, MotionEvent event)
{
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
int x=(int) event.getX();
int y=(int) event.getY();
X.setText("x coord is " + x);
Y.setText("y coord is " + y);
break;
case MotionEvent.ACTION_MOVE:
x=(int) event.getX();
y=(int) event.getY();
X.setText("x coord is " + x);
Y.setText("y coord is " + y);
break;
}
return true;
}
});
}
}
my clicklistener
public class MyButtonClickListener implements OnClickListener
{
@Override
public void onClick(View v)
{
ViewGroup relativeParent = (ViewGroup) v.getParent();
CustomEdittext edttxt = new CustomEdittext(v.getContext());
relativeParent.addView(edttxt);
edttxt.setOnLongClickListener(new MyLongClickListener());
}
}
** MyLongClickListner **
public class MyLongClickListner implements OnLongClickListener
{
@Override
public boolean onLongClick(View v)
{
ClipData dragdata = ClipData.newPlainText("","");
View.DragShadowBuilder shdwbldr = new View.DragShadowBuilder(v);
v.startDrag(dragdata, shdwbldr, v, 0);
v.setVisibility(View.INVISIBLE);
return true;
}
}
my draglistener
public class MyDragListener implements OnDragListener
{
private LayoutParams params;
@Override
public boolean onDrag(View v, DragEvent event)
{
View view = (View) event.getLocalState();
switch(event.getAction())
{
case DragEvent.ACTION_DRAG_STARTED:
params = (RelativeLayout.LayoutParams) view.getLayoutParams();
break;
case DragEvent.ACTION_DRAG_ENTERED:
int x = (int) event.getX();
int y = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_EXITED :
break;
case DragEvent.ACTION_DRAG_LOCATION :
x= (int) event.getX();
y = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_ENDED :
break;
case DragEvent.ACTION_DROP:
x = (int) event.getX();
y = (int) event.getY();
params.leftMargin = x;
params.topMargin = y;
view.setLayoutParams(params);
view.setVisibility(View.VISIBLE);
break;
default: break;
}
return true;
}
}
my custom edit text
public class CustomEdittext extends EditText
{
Paint paint;
public CustomEdittext(Context context){
super(context);
init();
}
public CustomEdittext(Context context, AttributeSet attr){
super(context, attr);
init();
}
public void init(){
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4);
paint.setColor(Color.BLUE);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}
}
my main xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#CDC2C0"
android:id="@+id/ondraglayout">
<TextView
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_alignParentBottom="true"
android:id="@+id/yvalue"/>
<TextView
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_above="@id/yvalue"
android:id="@+id/xvalue"/>
<Button
android:layout_height="wrap_content"
android:text="T"
android:layout_width="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:id="@+id/mainButton1"/>
</RelativeLayout>
Upvotes: 2
Views: 4054
Reputation: 374
Alright, after some research i got this working. Here is the implementation, made a few changes from your initial approach.
Firstly, i've changed you xml to some extent.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ondraglayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CDC2C0"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/dropLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/xvalue">
</RelativeLayout>
<TextView
android:id="@+id/yvalue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/xvalue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/yvalue"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/mainButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="T" />
</RelativeLayout>
I hope it is fine.
Secondly, as you can see in the xml, another empty layout has been added. The dropLayout is where we will drop the items. In your activity, reference this layout, then set the drag listener on it.
dropLayoutNew.setOnDragListener(dragListener);
dropLayoutNew.setOnTouchListener(otl);
The on touch listener is below, i commented out your implementation:
private View.OnTouchListener otl = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return true; // the listener has consumed the event
}
};
This is in the same activity, ie the MainActivity. Now, as for the last change i've made. I have created the on drag listener within the MainActivity itself, because i was somehow not able to debug that portion of code,the drag listener from another class(separate issue). So, for the drag listener, paste the below code in your MainActivity.
View.OnDragListener dragListener = new View.OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
View view = (View) event.getLocalState();
ViewGroup vg = (ViewGroup) v.getParent();
RelativeLayout rl = (RelativeLayout)vg.findViewById(R.id.dropLayout);
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
params = (RelativeLayout.LayoutParams) view.getLayoutParams();
break;
case DragEvent.ACTION_DRAG_ENTERED:
int x = (int) event.getX();
int y = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DRAG_LOCATION:
x = (int) event.getX();
y = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_ENDED:
break;
case DragEvent.ACTION_DROP:
int childCountDropped = rl.getChildCount();
System.out.println("Child Count of Views::::::Dropped" + childCountDropped);
x = (int) event.getX();
y = (int) event.getY();
params.leftMargin = x;
params.topMargin = y;
view.setLayoutParams(params);
view.setVisibility(View.VISIBLE);
break;
default:
break;
}
return true;
}
};
You can see some code added, but it does not change ur implementation. I wanted to check number of child items in the Relative Layout. I initially thought that it will give me a clear idea about the target layout(where items are being dropped). None the less, this is now working as you wanted. I checked it on a nexus 5 emulator, running 6.0. Do check it for other versions as well.
Conclusion: I am not sure as to why the drag listener was not working when referenced from another class, but none the less, it is working as you wanted now. The onTouchListener, again, you had a different implementation from mine. Maybe we will have to look into some more details on that. The main diff i did was to change the drop layout, you were doing it on the parent, i did it on another child. Rest mostly its the same. I would recommend to try out some other implementation as well, share with us the result.
I hope this code helps, let me know if this does not work.
Upvotes: 3