I want to make my slider be always on top. - Already done.
But I cant make him move. What changes should I do?
public class SliderOnTop extends Service {
private SeekBar seekBar;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
RelativeLayout layout = new RelativeLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
seekBar = new SeekBar(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, 45);
lp.bottomMargin = 0;
lp.leftMargin = 0;
layout.addView(seekBar, lp);
wm.addView(layout, params);
}
}
You could probably listen to onTouch events on your View, and then change the margins accordingly.
Related
I want to create a floating action button that keep running like DU Speed Booster.
Something like iOS assistive touch.
Here is a picture.
For doing this you might need to have this permission
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Create a Service and put this code inside OnCreate()
public class ChatHeadService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
#Override public IBinder onBind(Intent intent) {
// Not used
return null;
}
#Override public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.android_head);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.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);
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null) windowManager.removeView(chatHead);
}
}
Start serviceusing below code
startService(new Intent(context, ChatHeadService.class));
Please refer this blog for complete example http://androidsrc.net/facebook-chat-like-floating-chat-heads/
In service for displaying custom view over all windows I need to set onClick listener.
#Override public void onCreate() {
super.onCreate();
mContext = this;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout parent = (LinearLayout) inflater.inflate(R.layout.result_layout,
null);
// Here i need to add onClick listener
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.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(parent, params);
}
I tried to create button lister from inflater but without luck. What is the right approach to set click event listener for selected button by button ID?
Many thanks for any advice.
Resolved using the following code which is works in the service well:
#Override public void onCreate() {
super.onCreate();
mContext = this;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
final LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mParentLayout = (LinearLayout) inflater.inflate(R.layout.result_layout,
null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.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(mParentLayout, params);
Button b = (Button) mParentLayout.findViewById(R.id.closeButton);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
windowManager.removeView(mParentLayout);
}
});
}
Inspired from:
Could not get Touch event for TYPE_SYSTEM_OVERLAY
Android can play tricks on what you think might work, but doesn't.
First, What I typically do is from onCreate() I place a call to:
InitializePage(); where I then put all my initialize code. It's just my style.
Then in my InitializePage() function I initialize the button, then enter the OnClickListener. I use Android Studio with Intellisense so it writes the code for me....
mSendButton = (TextView)findViewById(R.id.send_button1);
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{.....
});
It should be that easy. Good luck
How can longclick to select a text in WebView in a Service. I added a WebView by the WindowManager, when a url is loaded and a longclick to select text is done. The selected text is not visible and can not be selected.
How can I fix it ?
public class BtService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
public static final int WINDOW_EXPAND_FLAGS = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_DIM_BEHIND
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
#Override
public void onCreate() {
super.onCreate();
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WINDOW_EXPAND_FLAGS, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 0;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
LinearLayout view = new LinearLayout(this);
view.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
WebView wv = new WebView(this);
wv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
view.addView(wv);
wv.loadUrl("https://tinhte.vn");
windowManager.addView(view, params);
}}
Also this will require the android.permission.SYSTEM_ALERT_WINDOW permission.
When webview loaded, longclick in text to select text,-> action mode don't show
I am trying to create a draggable imageView ("chatHead" in the code, kinda like the chat head of Facebook)
I followed the instruction on the android website but whereever I drag the imageview, it always ends up at the left upper corner. (with x,y cordinate being (0,0) ~ (90,90))
Later on I found out the problem is that the case: MotionEvent.ACTION_MOVE is only entered when my touch is around the imageView location.
And when I drag a bit further away from the imageView, ACTION_MOVE is no longer entered. And instead the case DragEvent.ACTION_DRAG_EXIT is executed.
Can someone tell me how can I expand the area for the ACTION_MOVE to be executed or what is the problem. I would like to locate the imageView at whichever location I want on the screen.
( you may just focus on onDragListener, the MyDragShadowBuilder is a customized extending DragShawdowBuilder and onLongClickListener is just to trigger the drag)
How to keep the imageView even the app is closed?
public class ChatHead extends Service {
private WindowManager windowManager;
private ImageView chatHead;
private WindowManager.LayoutParams params;
private final String CHAT_TAG ="CHAT";
private int cor_x = 0;
private int cor_y = 0;
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override public void onCreate() {
super.onCreate();
ImageView image = new ImageView(this);
Log.d("", "created");
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new ImageView(this);
chatHead.setTag(CHAT_TAG);
chatHead.setImageResource(R.drawable.chat_icon);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 300;
params.y = 300;
chatHead.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
ClipData.Item item = new ClipData.Item(v.getTag().toString());
String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};
ClipData dragData = new ClipData(v.getTag().toString(), mimeTypes,item);
View.DragShadowBuilder myShadow = new MyDragShadowBuilder(chatHead);
// Starts the drag
v.startDrag(dragData, // the data to be dragged
myShadow, // the drag shadow builder
null, // no need to use local data
0 // flags (not currently used, set to 0)
);
return false;}
});
chatHead.setOnDragListener(new View.OnDragListener() {
#Override
public boolean onDrag(View v, DragEvent event) {
//cor_x = ((int) chatHead.getX());
//cor_y = ((int) chatHead.getY());
switch (event.getAction()){
case DragEvent.ACTION_DRAG_ENTERED : { Log.d("", "x:"+ event.getX()+"y:"+event.getY());break;}
case DragEvent.ACTION_DRAG_STARTED : { Log.d("", "x:"+ event.getX()+" y:"+event.getY());break;}
case MotionEvent.ACTION_MOVE: {
cor_x = ((int) event.getX());
cor_y = ((int) event.getX());
Log.d("", "x:"+ cor_x+" y:"+cor_y);
break;}
case DragEvent.ACTION_DRAG_EXITED:{
Log.d("", "x:"+ cor_x+" y:"+cor_y);
break;
}
case DragEvent.ACTION_DRAG_ENDED : {
if(windowManager!=null && params!=null){
params.x = cor_x;
params.y = cor_y;
Log.d("", "x:"+ cor_x+" y:"+cor_y);
windowManager.removeView(chatHead);
windowManager.addView(chatHead, params);
}
return false;
}
}
return false;
}
});
windowManager.addView(chatHead, params);
}
If I understand what you mean, your problem is that you don't get the MotionEvent.ACTION_MOVE unless your finger is above your image.
Well that is because the concept of DragListener is that the View that register that listener, accept the events. So the only view in your layout that register to those events is chatHead, and he gets only the events that occur above him.
So if you want to get all the events in layout you must register view that take the whole screen space. So the quickest solution is to wrap the view with container that take the whole screen, and register it instead the chatHead to the DragListener. Somethong like:
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
RelativeLayout container = new RelativeLayout(this);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
chatHead = new ImageView(this);
chatHead.setTag(CHAT_TAG);
chatHead.setImageResource(R.drawable.chat_icon);
RelativeLayout.LayoutParams chatHeadParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
chatHeadParams.addRule(Gravity.TOP | Gravity.LEFT) ;
chatHeadParams.leftMargin = 300;
chatHeadParams.topMargin = 300;
container.addView(chatHead, chatHeadParams);
windowManager.addView(container, params);
And changing the line:
chatHead.setOnLongClickListener(new View.OnLongClickListener() {
to:
container.setOnLongClickListener(new View.OnLongClickListener() {
You may also adjust additional things because the DragEvent event.getX() and event.getX() will return different values according to the View itself and the DragEvent.Action type.
Hi I need a floating bubble on top of my activity and I decided to use a service for that. Everything works well except that in Android 4.xx devices the imageView is not being animated. I have added listeners to the animation and the animation is run (it starts, repeats... and also the values change) but the imageView does not move. It works perfectly well on Android 5.x devices but not 4.x. Anybody has any idea why?
Here is the code:
public class SellFloatingBubbleService extends Service {
private WindowManager windowManager;
private ImageView imageView;
#Override
public void onCreate() {
super.onCreate();
imageView = new ImageView(this);
imageView.setImageResource(R.drawable.tabbar_tooltip_v3);
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT,
LayoutParams.TYPE_PHONE,
LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
layoutParams.y = (int) TypedValue.applyDimension(TypedValue
.COMPLEX_UNIT_PX, getResources().getDimensionPixelOffset(R.dimen
.sell_button_height), getResources().getDisplayMetrics());
windowManager.addView(imageView, layoutParams);
imageView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
stopSelf();
return true;
}
});
/**
* When these animations will end they will revert and then play endlessly.
*/
AnimatorSet bouncer = new AnimatorSet();
ObjectAnimator animX = ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 0.8f);
animX.setRepeatMode(ValueAnimator.REVERSE);
animX.setRepeatMode(-1);
ObjectAnimator animY = ObjectAnimator.ofFloat(imageView, "scaleY", 1f, 0.8f);
animY.setRepeatMode(ValueAnimator.REVERSE);
animY.setRepeatCount(-1);
bouncer.playTogether(animX, animY);
bouncer.setDuration(1000);
bouncer.setInterpolator(new AccelerateDecelerateInterpolator());
bouncer.start();
}
#Override
public void onDestroy() {
imageView.setVisibility(View.GONE);
windowManager.removeView(imageView);
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
I have tried the same animation on another view, not in a service and it works. I also tried replacing ObjectAnimator by the old animations and the problem is still the same.
Is there something wrong about the code?
Putting ImageView inside LinearLayout fixed the problem of the imageView not being animated.
Here is the code:
public class SellFloatingBubbleService extends Service {
public static final int ANIMATION_DURATION = 500;
private WindowManager windowManager;
private ImageView imageView;
private int animationDistance;
private LinearLayout layout;
private static SellFloatingBubbleService instance = null;
public static boolean isInstanceCreated() {
return instance != null;
}
#Override
public void onCreate() {
super.onCreate();
BusProvider.getInstance().post(new BubbleWillBeShownEvent());
instance = this;
/**
* Animations do not work in Android 4.XX if view is not added inside a view group
*/
layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
imageView = new ImageView(this);
layout.addView(imageView, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
imageView.setImageResource(R.drawable.tabbar_tooltip_v);
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
animationDistance = (int) getResources().getDimension(R.dimen.sell_bubble_animation_height);
final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
LayoutParams.WRAP_CONTENT,
(int) getResources().getDimension(R.dimen.sell_bubble_window_height),
LayoutParams.TYPE_PHONE,
LayoutParams.FLAG_NOT_TOUCH_MODAL, //touch events are transmitted to windows below
PixelFormat.TRANSLUCENT);
layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
layoutParams.windowAnimations = android.R.style.Animation_Toast;
int sellButtonHeight = getResources().getDimensionPixelOffset(R.dimen
.sell_button_height);
layoutParams.y = sellButtonHeight / 2;
windowManager.addView(layout, layoutParams);
createAndStartAnimation();
}
private void createAndStartAnimation() {
/**
* When these animations will end they will revert and then play endlessly.
*/
float startValue = imageView.getY();
float endValue = imageView.getY() - animationDistance;
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator animYUp = ObjectAnimator.ofFloat(imageView, "y", startValue,
endValue);
animYUp.setRepeatMode(ValueAnimator.REVERSE);
animYUp.setRepeatCount(ValueAnimator.INFINITE);
animYUp.setDuration(ANIMATION_DURATION);
animYUp.setInterpolator(new DecelerateInterpolator()); //decelerate interpolator for up
ObjectAnimator animYDown = ObjectAnimator.ofFloat(imageView, "y", endValue,
startValue);
animYDown.setRepeatCount(ValueAnimator.INFINITE);
animYDown.setDuration(ANIMATION_DURATION);
animYDown.setInterpolator(new AccelerateInterpolator()); //accelerate interpolator for down
animatorSet.play(animYDown).after(animYUp);
animatorSet.start();
}
#Override
public void onDestroy() {
BusProvider.getInstance().post(new BubbleWillBeHiddenEvent());
instance = null;
imageView.setVisibility(View.INVISIBLE);
windowManager.removeView(layout);
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}