I've followed this tutorial http://android-er.blogspot.co.id/2014/01/implement-drag-and-drop-movable.html with some modification. I want to show image on it and make the pop up draggable.
now it's work. but the problem is the image can not move to the corner of the screen. can anyone give me a solution about this issue? any suggestion would be appreciated
this my layout
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rootView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/imgResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/dismiss"
android:paddingTop="16dp"
android:text="close"/>
</LinearLayout>
and this my activity class
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btnOpenPopup = (Button) findViewById(R.id.openpopup);
btnOpenPopup.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View arg0) {
LayoutInflater layoutInflater =
(LayoutInflater)getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.popup, null);
final PopupWindow popupWindow = new PopupWindow(
popupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
Button btnDismiss = (Button)popupView.findViewById(R.id.dismiss);
ImageView imageView = (ImageView) popupView.findViewById(R.id.imgResult);
int imageResource = getResources().getIdentifier("#drawable/toy", null, getPackageName());
Drawable res = getResources().getDrawable(imageResource);
imageView.setImageDrawable(res);
btnDismiss.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View v) {
popupWindow.dismiss();
}});
popupWindow.showAsDropDown(btnOpenPopup, 50, -30);
popupView.setOnTouchListener(new OnTouchListener() {
int orgX, orgY;
int offsetX, offsetY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
orgX = (int) event.getX();
orgY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
offsetX = (int)event.getRawX() - orgX;
offsetY = (int)event.getRawY() - orgY;
popupWindow.update(offsetX, offsetY, -1, -1, true);
break;
}
return true;
}});
}
});
}
}
Related
I have an Android app with a Service to Overlay a button on Android (like Facebook chat bubble).
I want to show a layout (overlay.xml) when the user click on the icon but I can't show the layout with the good dimension.
This is my result :
This is my OverlayShowingService.class :
public class OverlayShowingService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
private Boolean _enable = true;
#Override
public IBinder onBind(Intent intent) {
_enable=false;
return null;
}
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.mipmap.ic_launcher);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
windowManager.addView(chatHead, params);
chatHead.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
LayoutInflater layoutInflater = (LayoutInflater)getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.overlay, null);
final PopupWindow popupWindow = new PopupWindow(popupView,
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
popupWindow.update();
Button btnDismiss = (Button)popupView.findViewById(R.id.dismiss);
Button endService= (Button) popupView.findViewById(R.id.endService);
endService.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stopSelf();
Toast.makeText(getApplicationContext(), "Service Terminated", Toast.LENGTH_LONG).show();
}
});
btnDismiss.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "Popup Terminated", Toast.LENGTH_LONG).show();
popupWindow.dismiss();
_enable=true;
}
});
if(_enable){
popupWindow.showAsDropDown(chatHead, 50, -30);
_enable=false;
}
else if(!_enable) {
Log.d("FALSE", "FALSE");
}
}
});
try {
chatHead.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams paramsF = params;
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
#Override public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = paramsF.x;
initialY = paramsF.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, paramsF);
break;
}
return false;
}
});
} catch (Exception ignored) {}
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null) windowManager.removeView(chatHead);
}
}
This is the layout overlay.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="vertical"
android:layout_margin="5dp"
android:background="#545454">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's a PopupWindow"
android:textSize="40sp"
android:textColor="#ffffff" />
<Button
android:id="#+id/dismiss"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Dismiss Popup"
android:textColor="#ffffff" />
<Button
android:id="#+id/endService"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Finish Service"
android:textColor="#ffffff" />
</LinearLayout>
Edit: This is an alternate approach that mimics a popup window. I have kept the first answer with a altert dialog approach after the following explanation and code. Either way will work, but this new way may be preferable since it looks more like a popup window.
This approach simply adds the overlay.xml layout into a view that is place on the screen just like the chatHead view is.
OverlayShowingService.java
public class OverlayShowingService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
private Boolean _enable = true;
#Override
public IBinder onBind(Intent intent) {
_enable = false;
return null;
}
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.mipmap.ic_launcher);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
windowManager.addView(chatHead, params);
chatHead.post(new Runnable() {
#Override
public void run() {
params.x = (int) chatHead.getBottom() + 50;
params.y = (int) chatHead.getRight() - 30;
}
});
chatHead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
final View popupView = layoutInflater.inflate(R.layout.overlay, null);
final PopupWindow popupWindow = new PopupWindow(popupView,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.update();
Button btnDismiss = (Button) popupView.findViewById(R.id.dismiss);
Button endService = (Button) popupView.findViewById(R.id.endService);
endService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
windowManager.removeViewImmediate(popupView);
stopSelf();
Toast.makeText(getApplicationContext(), "Service Terminated", Toast.LENGTH_LONG).show();
}
});
btnDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "Popup Terminated", Toast.LENGTH_LONG).show();
// popupWindow.dismiss();
windowManager.removeViewImmediate(popupView);
_enable = true;
}
});
if (_enable) {
windowManager.addView(popupView, params);
// popupWindow.showAsDropDown(chatHead, 50, -30);
_enable = false;
} else if (!_enable) {
Log.d("FALSE", "FALSE");
}
}
});
try {
chatHead.setOnTouchListener(new View.OnTouchListener() {
private WindowManager.LayoutParams paramsF = params;
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = paramsF.x;
initialY = paramsF.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, paramsF);
break;
}
return false;
}
});
} catch (Exception ignored) {
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null) windowManager.removeView(chatHead);
}
}
The first approach using an alert dialog.
Your code works as-is for API 21 and below. Something changed with API 22 that is prohibiting what you want to do.
I think the primary issue is with the popup and the service environment. I have modified your code to use an AlertDialog with the type TYPE_SYSTEM_ALERT. Although the styling is not what you want, it does work otherwise. You may be able to get it to style differently if you play with it a little.
Another alternative would be to start an activity from your service. An activity-based approach will present you with a more pliable (and forgiving) environment to do what you want with the UI. (This is not as straight-forward as one may think.)
Below is the code that works as a system-level alert. Here is a screen shot.
OverlayShowingService
chatHead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
final AlertDialog alertDialog = new AlertDialog.Builder(arg0.getContext(),
R.style.Theme_AppCompat_Dialog_Alert).create();
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
final View popupView = layoutInflater.inflate(R.layout.overlay, null);
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.setView(popupView);
Button btnDismiss = (Button) popupView.findViewById(R.id.dismiss);
Button endService = (Button) popupView.findViewById(R.id.endService);
endService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alertDialog.dismiss();
stopSelf();
Toast.makeText(getApplicationContext(), "Service Terminated", Toast.LENGTH_LONG).show();
}
});
btnDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "Popup Terminated", Toast.LENGTH_LONG).show();
alertDialog.dismiss();
}
});
alertDialog.show();
}
});
As I stated in my first answer, you are having this issue with API 22 and later. Your code works OK for API 21 and earlier.
You are running afoul of changes made to PopupWindow in API level 22. See this documentation.
Fix issue #17789629: PopupWindow overlaps with navigation bar.
The Lollipop release introduced a feature that allowed
apps to extend under the navigation bar. This also means
any popup window that is anchored to the bottom of its
parent window will overlap with the navigation bar if the
parent window is extending underneath the navigation bar.
This change introduces a new window flag
(FLAG_LAYOUT_ATTACHED_IN_DECOR) that allows the app to
specify if the popup window should be attached to the decor
frame of the parent window thereby avoiding an overlap
with the screen decorations.
By default the flag is set on SDK version LOLLIPOP_MR1 or
greater and cleared on lesser SDK versions.
You can turn off this flag with the setAttachedInDecor method of PopupWindow.
Add the following code to OverlayShowingService.java after popupWindow.update() in the OnClickListener and you should be good to go.
// Turn off this functionality introduced in API 22.
// See documentation for FLAG_LAYOUT_ATTACHED_IN_DECOR in
// WindowManager.LayoutParams
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
popupWindow.setAttachedInDecor(false);
}
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'm trying to simulate swapping two views (one goes up and ones go down) with Translate animation.
Basically, it swaps and re-swap again.
This is my activity.
LinearLayout topView, belowView;
TextView foo, bar;
int viewHeight;
boolean noSwap = true;
private static int ANIMATION_DURATION = 3000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_slide);
topView = (LinearLayout) findViewById(R.id.top_view);
belowView = (LinearLayout) findViewById(R.id.below_view);
foo = (TextView) findViewById(R.id.foo);
bar = (TextView) findViewById(R.id.bar);
ImageButton btnSwitch = (ImageButton) findViewById(R.id.switch_btn);
ViewTreeObserver viewTreeObserver = foo.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
foo.getViewTreeObserver().addOnGlobalLayoutListener(this);
viewHeight = foo.getHeight();
foo.getLayoutParams();
}
});
}
btnSwitch.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
if (noSwap) {
//Log.d("Swap Status", "Not Swapping yet ? " + true);
TranslateAnimation ta1 = new TranslateAnimation(0, 0, 0, viewHeight);
ta1.setDuration(ANIMATION_DURATION);
ta1.setFillAfter(true);
topView.startAnimation(ta1);
topView.bringToFront();
belowView.setY(0);
TranslateAnimation ta2 = new TranslateAnimation(0, 0, 0, -viewHeight);
ta2.setDuration(ANIMATION_DURATION);
ta2.setFillAfter(true);
belowView.startAnimation(ta2);
belowView.bringToFront();
noSwap = false;
} else {
//Log.d("Swap Status", "Swapped already ? " + true);
TranslateAnimation ta1 = new TranslateAnimation(0, 0, viewHeight, 0);
ta1.setDuration(ANIMATION_DURATION);
ta1.setFillAfter(true);
topView.startAnimation(ta1);
topView.bringToFront();
belowView.setY(0);
TranslateAnimation ta2 = new TranslateAnimation(0, 0, 0, viewHeight);
ta2.setDuration(ANIMATION_DURATION);
ta2.setFillAfter(true);
belowView.startAnimation(ta2);
belowView.bringToFront();
noSwap = true;
}
}
});
}
This is the layout.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${packageName}.${activityClass}">
<LinearLayout
android:id="#+id/top_view"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/foo"
android:text="#string/foo"
android:textSize="30sp"
android:textColor="#android:color/holo_purple"
android:padding="10dp"
android:fontFamily="sans-serif-condensed"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:id="#+id/below_view"
android:layout_below="#+id/top_view"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/bar"
android:text="#string/bar"
android:textSize="30sp"
android:textColor="#android:color/holo_red_light"
android:padding="10dp"
android:fontFamily="sans-serif-condensed"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<ImageButton android:id="#+id/switch_btn"
style="?android:borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_import_export"
android:contentDescription="#string/swap"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
</RelativeLayout>
Everything seems fine until I click the Switch button for third times when the top view is supposed to go down and below view is to go up. But the starting position of the below view is not correct. I've tried setting several positions to below view but still can't get it right.
I've made a screencast about it here.
I think I get it right. Here's the working class.
LinearLayout topView, belowView;
TextView foo, bar;
int viewHeight;
boolean noSwap = true;
private static int ANIMATION_DURATION = 300;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_slide);
topView = (LinearLayout) findViewById(R.id.top_view);
belowView = (LinearLayout) findViewById(R.id.below_view);
foo = (TextView) findViewById(R.id.foo);
bar = (TextView) findViewById(R.id.bar);
ImageButton btnSwitch = (ImageButton) findViewById(R.id.switch_btn);
ViewTreeObserver viewTreeObserver = foo.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
foo.getViewTreeObserver().addOnGlobalLayoutListener(this);
viewHeight = foo.getHeight();
foo.getLayoutParams();
}
});
}
btnSwitch.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
if (noSwap) {
TranslateAnimation ta1 = new TranslateAnimation(0, 0, 0, viewHeight);
ta1.setDuration(ANIMATION_DURATION);
ta1.setFillAfter(true);
topView.startAnimation(ta1);
topView.bringToFront();
TranslateAnimation ta2 = new TranslateAnimation(0, 0, 0, -viewHeight);
ta2.setDuration(ANIMATION_DURATION);
ta2.setFillAfter(true);
belowView.startAnimation(ta2);
belowView.bringToFront();
noSwap = false;
} else {
TranslateAnimation ta1 = new TranslateAnimation(0, 0, viewHeight, 0);
ta1.setDuration(ANIMATION_DURATION);
ta1.setFillAfter(true);
topView.startAnimation(ta1);
topView.bringToFront();
TranslateAnimation ta2 = new TranslateAnimation(0, 0, -viewHeight, 0);
ta2.setDuration(ANIMATION_DURATION);
ta2.setFillAfter(true);
belowView.startAnimation(ta2);
belowView.bringToFront();
noSwap = true;
}
}
});
}
I am new at android programming. I have created a button using system overlay and a service. Now what I want is to click that button and get another overlay window of more 5 buttons. But the problem is that button doesn't take any click and don't allow me to open another overlay window. Here is the xml code I have used to draw the button--
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:id="#+id/l1"
android:layout_height="fill_parent"
tools:context=".OverlayActivity" >
<Button
android:id="#+id/mainButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:gravity="center_vertical"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:clickable="true"
android:visibility="visible"
android:focusable="true">
</Button>
and here is the code I have used to show the overlay button
#Override
public void onCreate() {
super.onCreate();
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View oView = layoutInflater.inflate(R.layout.activity_overlay, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
0 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(oView, params);
Button button = (Button)oView.findViewById(R.id.mainButton);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(OverlayService.this, "GotCha!!! ", Toast.LENGTH_LONG).show();
}
});
ViewGroup vg = (ViewGroup)oView.findViewById(R.id.l1);
final Display metrics = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
vg.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getActionMasked()){
case MotionEvent.ACTION_MOVE:
int x = (int)event.getX() - offset_x;
int y = (int)event.getY() - offset_y;
int w = metrics.getWidth()-100;
int h = metrics.getHeight()-100;
if(x > w){
x = w;
}
if(y > h){
y = h;
}
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
new ViewGroup.MarginLayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
lp.setMargins(x, y, 0, 0);
selected_item.setLayoutParams(lp);
break;
default:
break;
}
return true;
}
});
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getActionMasked()){
case MotionEvent.ACTION_DOWN:
offset_x = (int)event.getX();
offset_y = (int)event.getY();
selected_item = v;
break;
default:
break;
}
return false;
}
});
}
Any ideas guys? I am running out of time..Please
Better you use fragment for this
Create views using fragments, overlay a button above the fragment.
I'm basically trying to achieve drag&drop feature..
What i'm trying is that i provides sequence of images on the screen, if i click on any image available in images row that will be added to the Mains screen. But i'm getting problem that when i add new view into the Main Screen then all the other views also moved to top left corner.
Can you please tell me what is the problem...? Or kindly suggest me a tutorial or link where i can find solution.... or how to achieve this ?
I'm using Framelayout, So that i also achieve images overlapping...
This is the class in which all code is working:
public class drag extends Activity implements OnClickListener, OnTouchListener
{
ImageView img1;
Button btn,btn2;
FrameLayout layout;
LayoutParams params;
ImageView im , im2, im3 ,im4;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layout = (FrameLayout) findViewById(R.id.vg);
layout.setDrawingCacheEnabled(true);
im = (ImageView)findViewById(R.id.img1);
im.setDrawingCacheEnabled(true);
im.setOnTouchListener(this);
im.setOnClickListener(this);
btn = (Button)findViewById(R.id.btn1);
btn.setDrawingCacheEnabled(true);
btn.setOnClickListener(this);
btn.setOnTouchListener(this);
btn2 = (Button)findViewById(R.id.btn2);
btn2.setDrawingCacheEnabled(true);
btn2.setOnClickListener(this);
btn2.setOnTouchListener(this);
params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
btn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
im2 = new ImageView(drag.this);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.image);
im2.setImageBitmap(bm);
im2.setOnTouchListener(drag.this);
im2.setOnClickListener(drag.this);
layout.addView(im2, params);
}
});
btn2.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.image);
saveImage(bm);
}
});
}
public void saveImage(Bitmap myBitmap)
{
MediaStore.Images.Media.insertImage(getContentResolver(), myBitmap, "mmsImage" , "mmsimage");
}
int l, t, r, b;
int oldLeft, oldTop;
PointF p, curr;
#Override
public boolean onTouch(View view, MotionEvent me)
{
if (me.getAction() == MotionEvent.ACTION_DOWN)
{
//status = START_DRAGGING;
Log.i("status"," AAA dOWN");
img1 = new ImageView(this);
view.setDrawingCacheEnabled(true);
Bitmap mmsImage = Bitmap.createBitmap(view.getDrawingCache());
img1.setImageBitmap(mmsImage);
img1.setOnTouchListener(drag.this);
img1.setOnClickListener(drag.this);
oldLeft = (int)view.getLeft();
oldTop = (int)view.getTop();
p = new PointF(me.getRawX(), me.getRawY());
}
if (me.getAction() == MotionEvent.ACTION_MOVE)
{
Log.i("status"," AAA draging");
int xDiff = (int)(me.getRawX() - p.x);
int yDiff = (int)(me.getRawY() - p.y);
p.x = me.getRawX();
p.y = me.getRawY();
l = view.getLeft();
t = view.getTop();
r = view.getRight();
b = view.getBottom();
view.layout(l + xDiff, t + yDiff , r + xDiff, b + yDiff);
}
if (me.getAction() == MotionEvent.ACTION_UP)
{
Log.i("status"," AAA UP");
//captureUserMove(view);
}
return false;
}
}
Here is the XML :
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/vg"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/white" >
<ImageView
android:id="#+id/img1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/ic_launcher" />
<Button
android:id="#+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<Button
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
</FrameLayout>
You set params, but don't specify how to position the added view. Try this:
In onCreate()
params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.LEFT | Gravity.TOP; // you need this for margins to work
In the click listener:
// your x and y where you want the new view
params.leftMargin = x;
params.topMargin = y;
Putting
params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
inside
#Override
public void onClick(View v)
{
}
will work.