I made two nested RelativeLayouts, filled one with some TextViews and made reaction on finger drag guesture.
But it works badly:
1) moving group leaves garbage traces as if background does not redraw
2) the column with leftMargin==800 does not draw
The XML layout code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/stator"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp"
android:id="#+id/mover"
android:background="#android:color/darker_gray"
>
</RelativeLayout>
</RelativeLayout>
The java code:
public class SymbolPadActivity extends Activity {
private RelativeLayout mover;
private RelativeLayout stator;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mover = (RelativeLayout) findViewById(R.id.mover);
RelativeLayout.LayoutParams labelParams;
TextView textView;
for(int leftMargin = 0; leftMargin<1500; leftMargin += 200) {
for(int topMargin=0; topMargin<800; topMargin += 80) {
// I can't omit these 3 lines
labelParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
labelParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
labelParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
labelParams.leftMargin = leftMargin;
labelParams.topMargin = topMargin;
textView = new TextView(this);
textView.setText("(" + leftMargin + "," + topMargin + ")");
mover.addView(textView, labelParams);
}
}
stator = (RelativeLayout) findViewById(R.id.stator);
stator.setOnTouchListener(new View.OnTouchListener() {
private int startleft, starttop;
private float startx, starty;
private boolean started;
#Override
public boolean onTouch(View v, MotionEvent event) {
if( event.getActionMasked() == MotionEvent.ACTION_DOWN ) {
started = true;
startx = event.getX();
starty = event.getY();
startleft = mover.getLeft();
starttop = mover.getTop();
return true;
}
else if( event.getActionMasked() == MotionEvent.ACTION_UP ) {
started = false;
startx = starty = 0;
return true;
}
else if( event.getActionMasked() == MotionEvent.ACTION_MOVE ) {
mover.setLeft( startleft + (int)(event.getX() - startx) );
mover.setTop( starttop + (int)(event.getY() - starty) );
return true;
}
else {
return false;
}
}
});
}
}
How to implement my goal correctly (in brief)?
Related
How to apply pinch zoom on stickerView or ClipArt or custom view android. I tried this demo.
but not succeeded sometimes it will disappear view some time view become stuck, it worked fine when i want to zoom-in zoom-out from button but not on multi-touch.
screenshot:
Java
public class ClipArt extends RelativeLayout {
int baseh;
int basew;
int basex;
int basey;
ImageButton btndel;
ImageButton btnrot;
ImageButton btnscl;
RelativeLayout clip;
Context cntx;
boolean freeze = false;
int h;
int i;
ImageView image;
String imageUri;
boolean isShadow;
int iv;
RelativeLayout layBg;
RelativeLayout layGroup;
RelativeLayout.LayoutParams layoutParams;
public LayoutInflater mInflater;
int margl;
int margt;
float opacity = 1.0F;
Bitmap originalBitmap;
int pivx;
int pivy;
int pos;
Bitmap shadowBitmap;
float startDegree;
String[] v;
public ClipArt(Context paramContext) {
super(paramContext);
cntx = paramContext;
layGroup = this;
basex = 0;
basey = 0;
pivx = 0;
pivy = 0;
mInflater = ((LayoutInflater) paramContext.getSystemService("layout_inflater"));
mInflater.inflate(R.layout.clipart, this, true);
btndel = ((ImageButton) findViewById(R.id.del));
btnrot = ((ImageButton) findViewById(R.id.rotate));
btnscl = ((ImageButton) findViewById(R.id.sacle));
layoutParams = new RelativeLayout.LayoutParams(250, 250);
layGroup.setLayoutParams(layoutParams);
image = ((ImageView) findViewById(R.id.clipart));
image.setImageResource(R.drawable.ic_launcher);
setOnTouchListener(new View.OnTouchListener() {
final GestureDetector gestureDetector = new GestureDetector(ClipArt.this.cntx,
new GestureDetector.SimpleOnGestureListener() {
public boolean onDoubleTap(MotionEvent paramAnonymous2MotionEvent) {
return false;
}
});
public boolean onTouch(View paramAnonymousView, MotionEvent event) {
if (!ClipArt.this.freeze) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
layGroup.invalidate();
gestureDetector.onTouchEvent(event);
layGroup.performClick();
basex = ((int) (event.getRawX() - layoutParams.leftMargin));
basey = ((int) (event.getRawY() - layoutParams.topMargin));
break;
case MotionEvent.ACTION_MOVE:
int i = (int) event.getRawX();
int j = (int) event.getRawY();
layBg = ((RelativeLayout) getParent());
if ((i - basex > -(layGroup.getWidth() * 2 / 3))
&& (i - basex < layBg.getWidth() - layGroup.getWidth() / 3)) {
layoutParams.leftMargin = (i - basex);
}
if ((j - basey > -(layGroup.getHeight() * 2 / 3))
&& (j - basey < layBg.getHeight() - layGroup.getHeight() / 3)) {
layoutParams.topMargin = (j - basey);
}
layoutParams.rightMargin = -1000;
layoutParams.bottomMargin = -1000;
layGroup.setLayoutParams(layoutParams);
break;
}
return true;
}
return true;
}
});
this.btnscl.setOnTouchListener(new View.OnTouchListener() {
#SuppressLint({ "NewApi" })
public boolean onTouch(View paramAnonymousView, MotionEvent event) {
if (!ClipArt.this.freeze) {
int j = (int) event.getRawX();
int i = (int) event.getRawY();
layoutParams = (RelativeLayout.LayoutParams) layGroup.getLayoutParams();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
ClipArt.this.layGroup.invalidate();
ClipArt.this.basex = j;
ClipArt.this.basey = i;
ClipArt.this.basew = ClipArt.this.layGroup.getWidth();
ClipArt.this.baseh = ClipArt.this.layGroup.getHeight();
int[] loaction = new int[2];
layGroup.getLocationOnScreen(loaction);
margl = layoutParams.leftMargin;
margt = layoutParams.topMargin;
break;
case MotionEvent.ACTION_MOVE:
float f2 = (float) Math.toDegrees(Math.atan2(i - ClipArt.this.basey, j - ClipArt.this.basex));
float f1 = f2;
if (f2 < 0.0F) {
f1 = f2 + 360.0F;
}
j -= ClipArt.this.basex;
int k = i - ClipArt.this.basey;
i = (int) (Math.sqrt(j * j + k * k)
* Math.cos(Math.toRadians(f1 - ClipArt.this.layGroup.getRotation())));
j = (int) (Math.sqrt(i * i + k * k)
* Math.sin(Math.toRadians(f1 - ClipArt.this.layGroup.getRotation())));
k = i * 2 + ClipArt.this.basew;
int m = j * 2 + ClipArt.this.baseh;
if (k > 150) {
layoutParams.width = k;
layoutParams.leftMargin = (ClipArt.this.margl - i);
}
if (m > 150) {
layoutParams.height = m;
layoutParams.topMargin = (ClipArt.this.margt - j);
}
ClipArt.this.layGroup.setLayoutParams(layoutParams);
ClipArt.this.layGroup.performLongClick();
break;
}
return true;
}
return ClipArt.this.freeze;
}
});
this.btnrot.setOnTouchListener(new View.OnTouchListener() {
#SuppressLint({ "NewApi" })
public boolean onTouch(View paramAnonymousView, MotionEvent event) {
if (!ClipArt.this.freeze) {
layoutParams = (RelativeLayout.LayoutParams) ClipArt.this.layGroup.getLayoutParams();
ClipArt.this.layBg = ((RelativeLayout) ClipArt.this.getParent());
int[] arrayOfInt = new int[2];
layBg.getLocationOnScreen(arrayOfInt);
int i = (int) event.getRawX() - arrayOfInt[0];
int j = (int) event.getRawY() - arrayOfInt[1];
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
ClipArt.this.layGroup.invalidate();
ClipArt.this.startDegree = layGroup.getRotation();
ClipArt.this.pivx = (layoutParams.leftMargin + ClipArt.this.getWidth() / 2);
ClipArt.this.pivy = (layoutParams.topMargin + ClipArt.this.getHeight() / 2);
ClipArt.this.basex = (i - ClipArt.this.pivx);
ClipArt.this.basey = (ClipArt.this.pivy - j);
break;
case MotionEvent.ACTION_MOVE:
int k = ClipArt.this.pivx;
int m = ClipArt.this.pivy;
j = (int) (Math.toDegrees(Math.atan2(ClipArt.this.basey, ClipArt.this.basex))
- Math.toDegrees(Math.atan2(m - j, i - k)));
i = j;
if (j < 0) {
i = j + 360;
}
ClipArt.this.layGroup.setRotation((ClipArt.this.startDegree + i) % 360.0F);
break;
}
return true;
}
return ClipArt.this.freeze;
}
});
this.btndel.setOnClickListener(new View.OnClickListener() {
public void onClick(View paramAnonymousView) {
if (!ClipArt.this.freeze) {
layBg = ((RelativeLayout) ClipArt.this.getParent());
layBg.performClick();
layBg.removeView(ClipArt.this.layGroup);
}
}
});
}
public void disableAll() {
this.btndel.setVisibility(4);
this.btnrot.setVisibility(4);
this.btnscl.setVisibility(4);
}
public ImageView getImageView() {
return this.image;
}
public void setFreeze(boolean paramBoolean) {
this.freeze = paramBoolean;
}
}
Layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<ImageButton android:id="#+id/rotate" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:adjustViewBounds="true" android:background="#android:color/transparent" android:scaleType="fitCenter" android:src="#drawable/rotation"/>
<ImageButton android:id="#+id/sacle" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:adjustViewBounds="true" android:background="#android:color/transparent" android:scaleType="fitCenter" android:src="#drawable/pointer"/>
<ImageButton android:id="#+id/del" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:adjustViewBounds="true" android:background="#android:color/transparent" android:scaleType="fitCenter" android:src="#drawable/close"/>
<ImageView android:id="#+id/clipart" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"/>
</RelativeLayout>
I am developing an application in which I am using Drag and Drop functionality.
In that I am generating buttons OnClick.The code is working fine but when I drag the button to the corners of the relativelayout,button gets out of the layout. I want it to stay inside of the layout.
Before Dragging the button
After Dragging the button (on top corner in this example)
As you can see that the button is getting out of the layout whenever I drag it towards the end/corner of the layout, I want it to stay in the layout intact, display full button. How can I do that?
Thanks in advance.!
MainActivity.java
public class MainActivity extends Activity implements OnTouchListener {
Button btnAddButton;
RelativeLayout rl1;
int i = 1;
private int _xDelta;
private int _yDelta;
ViewGroup _root;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnAddButton = (Button) findViewById(R.id.btnAdd);
rl1 = (RelativeLayout) findViewById(R.id.relative_layout);
_root = (ViewGroup)findViewById(R.id.relative_layout);
btnAddButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
add(v);
}
});
}
public void add(View v) {
Button btn = new Button(MainActivity.this);
//btn.setId(i);
RelativeLayout.LayoutParams layoutParam = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
int a=(int) (Math.random()*100);
// Toast.makeText(MainActivity.this, String.valueOf(Math.random()*100), 1).show();//double a=Math.random();
layoutParam.leftMargin = 30+a;
if (i > 1) {
layoutParam.addRule(RelativeLayout.BELOW, (i - 1));
}
btn.setText("Button" + i);
rl1.addView(btn, layoutParam);
btn.setOnTouchListener(this);
i++;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
v.setLayoutParams(layoutParams);
break;
}
_root.invalidate();
return true;
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linear_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="AddButton"
android:text="Button" />
<RelativeLayout
android:id="#+id/relative_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/btnAdd" >
</RelativeLayout>
</RelativeLayout>
I was able to tackle this by using these conditions:
if ((v.getY() < lay.getY())) {
v.setX(xVal);
v.setY(yVal);
} else if (v.getX() < lay.getX()) {
v.setX(xVal);
v.setY(yVal);
} else if (v.getX() + v.getWidth() > lay.getX() + lay.getWidth()) {
v.setX(xVal);
v.setY(yVal);
} else if (v.getY() + v.getHeight() > lay.getY() + lay.getHeight()) {
v.setX(xVal);
v.setY(yVal);
} else {
for (int i = 0; i <= viewIdList.size() - 1; i++) {
if (v.getId() != viewIdList.get(i).getId()) {
View v3 = viewIdList.get(i);
Rect rect1 = new Rect(v.getLeft(), v.getTop(),
v.getRight(), v.getBottom());
v.getHitRect(rect1);
Rect rect2 = new Rect(v3.getLeft(), v3.getTop(),
v3.getRight(), v3.getBottom());
v3.getHitRect(rect2);
if (Rect.intersects(rect1, rect2)) {
System.out.println("overlap");
v.setX(xVal);
v.setY(yVal);
}
where v is the view (ImageView in my case) and this code is written in MotionEvent.ACTION_UP of onTouchListener.
I am creating programatically ImageViews and dragging them in the same layout.
I would like to disable overlapping for this ImageView. Is there a setting to be applied to disable overlap when I create every ImageView programatically or something else ?
public class MainActivity extends ActionBarActivity {
private int offset_x = 0;
private int offset_y = 0;
RelativeLayout canvas;
LinearLayout buttonslayout;
boolean isselected = false;
View selected_item = null;
int test1,test2;
Button save,newdoor,newwindow,rotate;
TextView xcoord,ycoord;
//static final int SNAP_GRID_INTERVAL = 43;
static final int SNAP_GRID_INTERVAL = 44;
static final int SNAP_GRID_INTERVAL2 = 25;
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
canvas = (RelativeLayout) findViewById(R.id.container2);
ViewGroup vg = (ViewGroup)findViewById(R.id.container3);
//buttonslayout = (LinearLayout) findViewById(R.id.container3);
save = (Button) findViewById(R.id.savebtn);
newdoor = (Button) findViewById(R.id.btnnewdoor);
newwindow = (Button) findViewById(R.id.btnnewwindow);
xcoord = (TextView) findViewById(R.id.xcoord);
ycoord = (TextView) findViewById(R.id.ycoord);
rotate = (Button) findViewById(R.id.rotate);
newwindow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
final int lungime = 66;
final int inaltime = 20;
final int []lastcoords = new int[2];
final int canvasWidth = canvas.getWidth();
final int canvasHeight = canvas.getHeight();
RelativeLayout mylayout = (RelativeLayout) findViewById(R.id.container2);
final View canvas = ((View) v.getParent());
final int []coordwall = new int[2];
mylayout.getLocationInWindow(coordwall);
final ImageView image = new ImageView(getBaseContext());
image.setBackgroundResource(R.drawable.element_window);
mylayout.addView(image);
image.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
offset_x = (int)event.getX();
offset_y = (int)event.getY();
selected_item = v;
isselected = true;
xcoord.setText("X: "+lastcoords[0]);
ycoord.setText("Y: "+lastcoords[1]);
Log.i("test","Isselected = "+isselected);
break;
default:
break;
}
return false;
}
});
rotate.setOnClickListener(new View.OnClickListener() {
int grad=0;
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(grad!=1)
{
image.setRotation(90);
grad=1;
}
else
{
image.setRotation(180);
grad=0;
}
}
});
mylayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
MarginLayoutParams marginParams = new MarginLayoutParams(v.getLayoutParams());
switch(event.getAction())
{
case MotionEvent.ACTION_UP:
isselected = false;
Log.i("test","Isselected = "+isselected);
break;
case MotionEvent.ACTION_MOVE:
if(isselected == true)
{
View canvas = ((View) v.getParent());
final int width = v.getWidth() / 2, height = v.getHeight() / 2;
int x = (int)event.getX() - offset_x;
int y = (int)event.getY() - offset_y;
int w = getWindowManager().getDefaultDisplay().getWidth() - 100;
int h = getWindowManager().getDefaultDisplay().getHeight() - 100;
int rawX = (int) event.getRawX(), rawY = (int) event.getRawY();
int x_coord = (int) event.getRawX() - coordwall[0] - width;
int y_coord = (int) event.getRawY() - coordwall[1] - height;
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
new ViewGroup.MarginLayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
if (rawY < coordwall[1] + inaltime / 2)
lp.topMargin = 0;
else
if (rawY >= coordwall[1] + canvasHeight - inaltime )
lp.topMargin = canvasHeight - inaltime*2;
else
lp.topMargin = y / SNAP_GRID_INTERVAL * SNAP_GRID_INTERVAL;
if(rawX < coordwall[0] + lungime / 2)
lp.leftMargin = 0;
else
if(rawX >= coordwall[0] + canvasWidth - lungime)
{
lp.leftMargin = canvasWidth - lungime*2;
Log.i("arry","leftmargin = " + lp.leftMargin);
}
else
lp.leftMargin = x / SNAP_GRID_INTERVAL * SNAP_GRID_INTERVAL;
lastcoords[0] = lp.leftMargin;
lastcoords[1] = lp.topMargin;
xcoord.setText("X: "+lp.leftMargin);
ycoord.setText("Y: "+lp.topMargin);
lp.setMargins(lp.leftMargin, lp.topMargin, 0, 0);
selected_item.setLayoutParams(lp);
}
break;
default:
break;
}
return true;
}
});
}
});
And the xml:
LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="horizontal"
tools:context="com.example.draganddrop.MainActivity"
tools:ignore="MergeRootFrame" >
<LinearLayout
android:id="#+id/container3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#848484"
android:orientation="vertical" >
<Button
android:id="#+id/savebtn"
style="#drawable/new_wall"
android:layout_width="100dp"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="#drawable/new_wall"
android:textSize="13sp" />
<Button
android:id="#+id/btnnewwindow"
android:layout_width="100dp"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="#drawable/new_window"
android:textSize="13sp" />
<Button
android:id="#+id/btnnewdoor"
android:layout_width="100dp"
android:layout_height="30dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:background="#drawable/new_door"
android:textSize="14sp" />
<TextView
android:id="#+id/xcoord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:text="X: " />
<TextView
android:id="#+id/ycoord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Y: " />
<Button
android:id="#+id/rotate"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rotate" />
</LinearLayout>
<RelativeLayout
android:id="#+id/container2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF" >
</RelativeLayout>
</LinearLayout>
It is not very clear what exactly You want to do, but if I am understand You the right way, You want to set some ImageViews to a layout programmatically? Why are Your Views overlapping? I think You have to set the layout Paramaters for Your view container:
//after onCreate in the activity, create the LinearLayout (for example)
//and set the LayoutParams, if You have no one declared in Your xml
LinearLayout linearLayout= new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
//then create the imageView, set the image inside and add it to the container
ImageView imageView = new ImageView(this);
imageView.setImageResource(R.drawable.your_image);
imageView.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
linearLayout.addView(imageView);
//set all as content
setContentView(linearLayout);
Have You done it in this way? If not, try it, also if You want to set multiple imageViews or some other Layout, You have to play a little bit with the LayoutParams.
I have a 5x5 grid (I ve drawn a matrix in canvas). I ve arranged the textviews in the the grid
in the order of a array..ie (5X5 ) array. The thing is I want to change the values on of the text view when I swipe horizontally or vertically.
Say suppose I am using a touch movement on the screen continuously from [4][0] to [4][2] I want to modify the values of the textviews in those places.
Any ideas?
This piece of code might help you:
public class MyClass extends Activity implements OnGestureListener{
ArrayList<TextView> tvs = new ArrayList<TextView>();
public void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.mygrid);
}
public void onResume() {
super.onResume();
GestureOverlayView gd = (GestureOverlayView)findViewById(R.id.gd);
LinearLayout g = (LinearLayout)findViewById(R.id.mygrid);
gd.addOnGestureListener(this);
g.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < 5; i++) {
LinearLayout row = new LinearLayout(this);
g.addView(row);
row.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams rowlp = (LayoutParams) row.getLayoutParams();
rowlp.width = LayoutParams.MATCH_PARENT;
rowlp.weight = 1;
rowlp.height = LayoutParams.WRAP_CONTENT;
row.setLayoutParams(rowlp);
for (int j = 0; j < 5; j++) {
TextView tv = new TextView(this);
row.addView(tv);
LinearLayout.LayoutParams lp = (LayoutParams) tv.getLayoutParams();
lp.height = LayoutParams.MATCH_PARENT;
lp.width = 0;
lp.weight = 1;
tv.setLayoutParams(lp);
tv.setText(String.valueOf(i * 5 + j));
tv.setTag(String.valueOf(i * 5 + j));
tv.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
tvs.add(tv);
if ((i * 5 + j) % 2 == 0)
tv.setBackgroundColor(0xff888888);
}
}
}
private boolean isPointInsideView(float x, float y, View view){
int location[] = new int[2];
view.getLocationOnScreen(location);
int viewX = location[0];
int viewY = location[1];
//point is inside view bounds
if(( x > viewX && x < (viewX + view.getWidth())) &&
( y > viewY && y < (viewY + view.getHeight()))){
return true;
} else {
return false;
}
}
#Override
public void onGesture(GestureOverlayView overlay, MotionEvent event) {
float x = event.getRawX();
float y = event.getRawY();
for (TextView v : tvs) {
if (isPointInsideView(x, y, v)) {
v.setText("HERE");
}
}
}
#Override
public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
}
#Override
public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
}
#Override
public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gd"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/mygrid"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.gesture.GestureOverlayView>
Hope it helps.
Edit2: replace the methods above with these for highly increased performance:
private TextView getAbove(float x, float y) {
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
if (isPointInsideView(x, y, tvs[i][j]))
return tvs[i][j];
return null;
}
#Override
public void onGesture(GestureOverlayView overlay, MotionEvent event) {
float x = event.getRawX();
float y = event.getRawY();
if (last == null || !isPointInsideView(x, y, last)) {
last = getAbove(x,y);
draw();
}
}
private void draw() {
if (last == null)
return;
last.setText("+");
}
private void reset() {
last = null;
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
tvs[i][j].setText(String.valueOf(i * 5 + j));
}
#Override
public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
reset();
}
#Override
public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
reset();
}
#Override
public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
last = getAbove(event.getRawX(), event.getRawY());
draw();
}
TextView[][] tvs = new TextView[5][5];
TextView last = null;
And make the arraylist into an TextView[5][5]
I try to make an app with multitouching and I use this code:
Multitouchng code
It works, but I've got problem, because in my app I've got HorizontalScrollView (HSV) and when I press buttons from begining of HSV I've got buttons Id (View.getId()) in "downTouchedViewsIndex", but when I scroll my HSV and press any button I have only layout's Id - nothing about buttons.
My touch code:
package com.lacrima.pianoo;
public class MainActivity extends Activity implements SeekBar.OnSeekBarChangeListener, OnTouchListener {
static private String TAG = "MainActivity";
public View parent;
private final ArrayList[] recentTouchedViewsIndex = new ArrayList[10];
private final ArrayList[] downTouchedViewsIndex = new ArrayList[10];
private final ArrayList<View> moveOutsideEnabledViews = new ArrayList<View>();
private List<Integer> list = new ArrayList<Integer>();
private final int mTouchSlop = 24;
AssetFileDescriptor des; // deskryptor do opisu wczytywanego pliku muzycznego (miejsce gdzie jesta zapisany dlugość i inne takie)
MediaPlayer[] mp = new MediaPlayer[36];// = new MediaPlayer();
//Pierwsza oktawa
Button button1, button2, button3, button4, button5, button6, button7;
Button button1_5, button2_5, button4_5, button5_5, button6_5;
//Druga oktawa
Button button8, button9, button10, button11, button12, button13, button14;
Button button8_5, button9_5, button11_5, button12_5, button13_5;
//Trzecia oktawa
Button button15, button16, button17, button18, button19, button20, button21;
Button button15_5, button16_5, button18_5, button19_5, button20_5;
SamplePlayer sound;
Integer[] soundIDs = new Integer[36];
private boolean[] whitePlays = new boolean[21];
private boolean[] blackPlays = new boolean[15];
private View[] whiteViews = new View[21];
private View[] blackViews = new View[15];
private int lastButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //Ustawienie ekranu horuzontalnie na sztywno
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
parent = findViewById(android.R.id.content).getRootView();
parent.setOnTouchListener(this);
SeekBar seek = (SeekBar) findViewById(R.id.seekBar);
final LockedHorizontalScrollView hsv = (LockedHorizontalScrollView)findViewById(R.id.hsv);
seek.setMax(948);
seek.setProgress(474);
seek.setOnSeekBarChangeListener(this);
hsv.post(new Runnable() {
#Override
public void run() {
hsv.scrollTo(474, 0);
}
});
sound = new SamplePlayer(this);
falsePlays();
buttonListeners();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
LockedHorizontalScrollView hsv = (LockedHorizontalScrollView)findViewById(R.id.hsv);
hsv.scrollTo(progress, 0);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
//uruchamiane w momencie kliknięcia na suwak
Log.d(TAG, "Tracking on");
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
//uruchamiane w momencie odkliknięcia suwaka
Log.d(TAG, "Tracking off");
}
#Override
protected void onDestroy() {
sound.release();
super.onDestroy();
}
#Override
public boolean onTouch(View v, MotionEvent event) {
// index of the pointer which starts this Event
final int actionPointerIndex = event.getActionIndex();
// resolve the action as a basic type (up, down or move)
int actionResolved = event.getAction() & MotionEvent.ACTION_MASK;
if (actionResolved < 7 && actionResolved > 4) {
actionResolved = actionResolved - 5;
}
if (actionResolved == MotionEvent.ACTION_DOWN || actionResolved == MotionEvent.ACTION_UP
|| actionResolved == MotionEvent.ACTION_CANCEL) {
dealEvent(actionPointerIndex, event, v, actionResolved);
}
return true;
}
private void dealEvent(final int actionPointerIndex, final MotionEvent event, final View eventView,
final int actionResolved) {
int rawX, rawY;
final int location[] = { 0, 0 };
eventView.getLocationOnScreen(location);
// Log.v("tag", location + "");
rawX = (int) event.getX(actionPointerIndex) + location[0];
rawY = (int) event.getY(actionPointerIndex) + location[1];
final int actionPointerID = event.getPointerId(actionPointerIndex);
ArrayList<View> hoverViews = getTouchedViews(rawX, rawY);
if (actionResolved == MotionEvent.ACTION_DOWN) {
downTouchedViewsIndex[actionPointerID] = (ArrayList<View>) hoverViews.clone();
lastButton = hoverViews.get(k-1).getId();
}
if(actionResolved == MotionEvent.ACTION_UP){
int k = hoverViews.size();
Log.d("klop", "Odklijniecie: " + hoverViews.get(k-1).getId());
lastButton = eventView.getId();
}
// deletes all views which where not clicked on ActionDown
if (downTouchedViewsIndex[actionPointerID] != null) {
final ArrayList<View> tempViews = (ArrayList<View>) hoverViews.clone();
tempViews.removeAll(downTouchedViewsIndex[actionPointerID]);
hoverViews.removeAll(tempViews);
}
if (recentTouchedViewsIndex[actionPointerID] != null) {
final ArrayList<View> recentTouchedViews = recentTouchedViewsIndex[actionPointerID];
final ArrayList<View> shouldTouchViews = (ArrayList<View>) hoverViews.clone();
if (!shouldTouchViews.containsAll(recentTouchedViews)) {
shouldTouchViews.removeAll(recentTouchedViews);
shouldTouchViews.addAll(recentTouchedViews);
final ArrayList<View> outsideTouchedViews = (ArrayList<View>) shouldTouchViews.clone();
outsideTouchedViews.removeAll(hoverViews);
}
recentTouchedViewsIndex[actionPointerID] = hoverViews;
hoverViews = shouldTouchViews;
} else {
recentTouchedViewsIndex[actionPointerID] = hoverViews;
}
if (actionResolved == MotionEvent.ACTION_UP) {
recentTouchedViewsIndex[actionPointerID] = null;
downTouchedViewsIndex[actionPointerID] = null;
}
for (final View view : hoverViews) {
int x, y;
view.getLocationOnScreen(location);
x = rawX - location[0];
y = rawY - location[1];
// View does not recognize that the Pointer is
// outside if the Pointer is not far away (>mTouchSlop)
if (recentTouchedViewsIndex[actionPointerID] != null) {
if (pointInView(x, y, mTouchSlop, view.getWidth(), view.getHeight())) {
if (!recentTouchedViewsIndex[actionPointerID].contains(view)) {
recentTouchedViewsIndex[actionPointerID].add(view);
}
} else if (moveOutsideEnabledViews.contains(view)) {
Log.v("tag", "outside but gets event");
recentTouchedViewsIndex[actionPointerID].add(view);
}
}
final MotionEvent me = MotionEvent.obtain(event.getDownTime(), event.getEventTime(), actionResolved, x, y,
event.getPressure(actionPointerIndex), event.getPressure(actionPointerIndex), event.getMetaState(),
event.getXPrecision(), event.getYPrecision(), event.getDeviceId(), event.getEdgeFlags());
me.setLocation(x, y);
if (!me.equals(event)) {
// deals the Event
view.onTouchEvent(me);
}
// debug
if (actionResolved == MotionEvent.ACTION_MOVE) {
Log.v("tag", "#" + actionPointerIndex + " Rawx:" + rawX + " rawy:" + rawY + " x:" + x + " y:" + y + " "
+ view.toString());
}
}
}
private ArrayList<View> getTouchedViews(final int x, final int y) {
final ArrayList<View> touchedViews = new ArrayList<View>();
final ArrayList<View> possibleViews = new ArrayList<View>();
if (parent instanceof ViewGroup) {
possibleViews.add(parent);
for (int i = 0; i < possibleViews.size(); i++) {
final View view = possibleViews.get(i);
final int location[] = { 0, 0 };
view.getLocationOnScreen(location);
if (((view.getHeight() + location[1] >= y) & (view.getWidth() + location[0] >= x) & (view.getLeft() <= x) & (view
.getTop() <= y)) || view instanceof FrameLayout) {
touchedViews.add(view);
possibleViews.addAll(getChildViews(view));
}
}
}
return touchedViews;
}
private ArrayList<View> getChildViews(final View view) {
final ArrayList<View> views = new ArrayList<View>();
if (view instanceof ViewGroup) {
final ViewGroup v = ((ViewGroup) view);
if (v.getChildCount() > 0) {
for (int i = 0; i < v.getChildCount(); i++) {
views.add(v.getChildAt(i));
}
}
}
return views;
}
private boolean pointInView(final float localX, final float localY, final float slop, final float width,
final float height) {
return localX >= -slop && localY >= -slop && localX < ((width) + slop) && localY < ((height) + slop);
}
public void addMoveOutsideEnabledViews(final View view) {
moveOutsideEnabledViews.add(view);
}
And xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#0A0A0A"
android:orientation="vertical" >
<SeekBar
android:id="#+id/seekBar"
android:layout_width="fill_parent"
android:layout_height="53dp" />
<com.lacrima.pianoo.LockedHorizontalScrollView
android:id="#+id/hsv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<Button...
</RelativeLayout>
</com.lacrima.pianoo.LockedHorizontalScrollView>
</LinearLayout>
My code is quite long so I puttet it on dropbox (whole project) and you can see what happend
Project
I think if you move the scrollbar you lose the focus of the first clicked button. two reasons:
- the Scrollview overrides the onTouchEvent and return true. --> the touch is consumed
- you lose focus of the first button. Try to add the Buttons with the addMoveOutsideEnabledViews Methode and see what happens.
I resolved my problem.
You don't need looking for button under touch. You have to take X and Y of your touch position and add your values from scrollView. Then you have to check, there are any button and start method:
rawX = (int) event.getX(actionPointerIndex) + location[0];
rawY = (int) event.getY(actionPointerIndex) + location[1];
scrollX = seek.getProgress() + rawX;
if (actionResolved == MotionEvent.ACTION_DOWN) {
findButton(scrollX, rawY, true);
}
if(actionResolved == MotionEvent.ACTION_UP || actionResolved == MotionEvent.ACTION_CANCEL) {
findButton(scrollX, rawY, false);
}