I wish to create a floating button which will hover over the entire Android screen. When the button or hovering icon is clicked, it should open a small popupwindow.
I was able to create the hovering icon using service class however I am unable to launch popupwindow. Whenever I click the floating icon, the error log says:
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageView;
import android.widget.PopupWindow;
/**
* Created by sejal on 17-Oct-15.
*/
public class bubble extends Service{
PopupWindow popw;
private WindowManager windowManager;
private ImageView floatingFaceBubble;
public void onCreate() {
super.onCreate();
floatingFaceBubble = new ImageView(this);
//a face floating bubble as imageView
floatingFaceBubble.setImageResource(R.drawable.bubble);
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//here is all the science of params
final LayoutParams myParams = new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT,
LayoutParams.TYPE_PHONE,
LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
myParams.gravity = Gravity.TOP | Gravity.LEFT;
myParams.x=0;
// add a floatingfacebubble icon in window
windowManager.addView(floatingFaceBubble, myParams);
try{
floatingFaceBubble.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getpopuppwindow();
}
});
//for moving the picture on touch and slide
floatingFaceBubble.setOnTouchListener(new View.OnTouchListener() {
LayoutParams paramsT = myParams;
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
private long touchStartTime = 0;
#Override
public boolean onTouch(View v, MotionEvent event) {
//remove face bubble on long press
/* if(System.currentTimeMillis()-touchStartTime> ViewConfiguration.getLongPressTimeout() && initialTouchX== event.getX()){
//// windowManager.removeView(floatingFaceBubble);
//// stopSelf();
// return false;
// } */
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
touchStartTime = System.currentTimeMillis();
initialX = myParams.x;
initialY = myParams.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
myParams.x = initialX + (int) (event.getRawX() - initialTouchX);
myParams.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(v, myParams);
break;
}
return false;
}
});
} catch (Exception e){
e.printStackTrace();
}
}
//(ViewGroup) floatingFaceBubble.findViewById(R.id.pop)
private void getpopuppwindow() {
try {
System.out.print("111111");
LayoutInflater inflater = (LayoutInflater)bubble.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
System.out.print("222222");
View layout = inflater.inflate(R.layout.popup,(ViewGroup) floatingFaceBubble.findViewById(R.id.pop));
System.out.print("333333");
popw = new PopupWindow(layout ,300,100 ,true) ;
System.out.print("444444");
popw.showAtLocation(layout, Gravity.CENTER,0,0);
}
catch(Exception e)
{
e.printStackTrace();
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
You should not do these ui operations in your service class. Because after you show your button service instance will be removed and there is no context when you click the button. I think you should follow similar approach like below.
Service Class:
Intent activityIntent = new Intent(context, MainActivity);
activityIntent.putExtra("showPopup", true);
context.startActivity(activityIntent);
Activity Class:
onCreate(){
boolean showPopUp = getIntent().getBooleanExtra("showPopup", false);
if(showPopUp){
// Show your popup here
}
}
Related
I want to make android app like the following site.
https://sectional-anatomy.org/ct-abdomen/ or like https://radiopaedia.org/cases/squamous-cell-carcinoma-oral-cavity
There are multiple pictures and these are changing by scrolling.
I have done something like that with imageswitcher and onTouch event with action_down and action_up but it doesn't work because when I remove my finger then it goes to the first image it doesn't stay where I left.
Here is my code:
package com.radiology.radiologymenu.tomografi;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;
import com.radiology.radiologymenu.R;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public class ImageChangeActivity extends AppCompatActivity {
private ImageSwitcher imageSwitcher;
private ImageView box;
// Size
private int frameHeight;
private int boxSize;
private int screenHeight;
// Position
private int boxY;
// Speed
private int boxSpeed;
// Score
private int score = 0;
// Initialize Class
private Handler handler = new Handler();
private Timer timer = new Timer();
// Status Check
private boolean action_flg = false;
private boolean start_flg = false;
private String pic;
private ArrayList<Integer> slidePictures;
private static final Integer[] image= {
R.drawable.sagittal_boyun_1, R.drawable.sagittal_boyun_2, R.drawable.sagittal_boyun_3, R.drawable.sagittal_boyun_4,
R.drawable.sagittal_boyun_5, R.drawable.sagittal_boyun_6, R.drawable.sagittal_boyun_7, R.drawable.sagittal_boyun_8,
R.drawable.sagittal_boyun_9, R.drawable.sagittal_boyun_10, R.drawable.sagittal_boyun_11,
R.drawable.sagittal_boyun_12, R.drawable.sagittal_boyun_13, R.drawable.sagittal_boyun_14, R.drawable.sagittal_boyun_15,
R.drawable.sagittal_boyun_16, R.drawable.sagittal_boyun_17, R.drawable.sagittal_boyun_18, R.drawable.sagittal_boyun_19,
R.drawable.sagittal_boyun_20, R.drawable.sagittal_boyun_21, R.drawable.sagittal_boyun_22, R.drawable.sagittal_boyun_23,
R.drawable.sagittal_boyun_24, R.drawable.sagittal_boyun_25, R.drawable.sagittal_boyun_26, R.drawable.sagittal_boyun_27,
R.drawable.sagittal_boyun_28, R.drawable.sagittal_boyun_29, R.drawable.sagittal_boyun_30, R.drawable.sagittal_boyun_31,
R.drawable.sagittal_boyun_32, R.drawable.sagittal_boyun_33, R.drawable.sagittal_boyun_34, R.drawable.sagittal_boyun_35,
R.drawable.sagittal_boyun_36, R.drawable.sagittal_boyun_37, R.drawable.sagittal_boyun_38, R.drawable.sagittal_boyun_39,
R.drawable.sagittal_boyun_40, R.drawable.sagittal_boyun_41, R.drawable.sagittal_boyun_42, R.drawable.sagittal_boyun_43,
R.drawable.sagittal_boyun_44, R.drawable.sagittal_boyun_45 };
int i = 0;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slide_activity_main);
pic = getIntent().getExtras().getString("pic");
slidePictures = (ArrayList<Integer>) getIntent().getExtras().getSerializable("slidePictures");
getView2(pic,slidePictures);
}
public void getView2(String strings, ArrayList<Integer> slidePictures){
setContentView(R.layout.slide_activity_main);
TextView textView = (TextView) findViewById(R.id.resimText);
textView.setText(strings.toString());
imageSwitcher = (ImageSwitcher) findViewById(R.id.imageSwitcher);
box = (ImageView) findViewById(R.id.box);
// Get screen size.
WindowManager wm = getWindowManager();
Display disp = wm.getDefaultDisplay();
Point size = new Point();
disp.getSize(size);
screenHeight = size.y;
boxSpeed = Math.round(screenHeight / 60); // 1280 / 60 = 21.333... => 21
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
#Override
public View makeView() {
ImageView imageView = new ImageView(getApplicationContext());
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
FrameLayout.LayoutParams params = new ImageSwitcher.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
imageView.setLayoutParams(params);
return imageView;
}
});
imageSwitcher.setImageResource(slidePictures.get(0));
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK))
{
finish();
}
return super.onKeyDown(keyCode, event);
}
public void changePos() {
// Move Box
if (action_flg == true) {
// Touching
boxY -= boxSpeed;
if (i<slidePictures.size()-1){
i++;
imageSwitcher.setImageResource(slidePictures.get(i));
}
} else {
// Releasing
boxY += boxSpeed;
if (i>0){
i--;
imageSwitcher.setImageResource(slidePictures.get(i));
}
}
// Check box position.
if (boxY < 0) boxY = 0;
if (boxY > frameHeight - boxSize) boxY = frameHeight - boxSize;
box.setY(boxY);
}
public boolean onTouchEvent(MotionEvent me) {
if (start_flg == false) {
start_flg = true;
// Why get frame height and box height here?
// Because the UI has not been set on the screen in OnCreate()!!
FrameLayout frame = (FrameLayout) findViewById(R.id.frame);
frameHeight = frame.getHeight();
boxY = (int)box.getY();
// The box is a square.(height and width are the same.)
boxSize = box.getHeight();
timer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
changePos();
}
});
}
}, 0, 40);
} else {
if (me.getAction() == MotionEvent.ACTION_DOWN) {
action_flg = false;
} else if (me.getAction() == MotionEvent.ACTION_UP) {
action_flg = true;
}
}
return true;
}
}
I am trying to use a Bulider from a library that i have imported in my project but for some reason the Builder doesn't accept 'this' as Service context. if anyone can help me out i would truly appreciate it. Thanks
import android.app.Service;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import com.oguzdev.circularfloatingactionmenu.library.FloatingActionMenu;
import com.oguzdev.circularfloatingactionmenu.library.FloatingActionButton;
import com.oguzdev.circularfloatingactionmenu.library.SubActionButton;
import com.example.andrew.reddit2go.R;
import java.util.Calendar;
/**
* Created by Justeen on 2015-02-26.
*/
public class FloatService extends Service {
private WindowManager windowManager;
public TextView textView;
private final IBinder mBinder = new LocalBinder();
private FloatingActionButton rightLowerButton;
private FloatingActionButton topCenterButton;
private FloatingActionMenu rightLowerMenu;
private FloatingActionMenu topCenterMenu;
private boolean serviceWillBeDismissed;
//keep track of an instance to communicate with
private static FloatService floatingInstance;
public class LocalBinder extends Binder {
FloatService getService() {
// Return this instance of LocalService so clients can call public methods
return FloatService.this;
}
}
public FloatService(){
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
serviceWillBeDismissed = false;
floatingInstance = FloatService.this;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
textView = new TextView(this);
textView.setBackgroundResource(R.drawable.icon);
textView.setTypeface(null, Typeface.BOLD);
textView.setTextColor(Color.GRAY);
textView.setText("0");
Resources res = getResources();
Drawable shape = res.getDrawable(R.drawable.gradient_box);
//textView.findViewById(R.id.textView);
textView.setBackground(shape);
final 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(textView, params);
try {
textView.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
private final int MAX_CLICK_DURATION = 200;
private long startClickTime;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
startClickTime = Calendar.getInstance().getTimeInMillis();
return true;
case MotionEvent.ACTION_UP:
long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
//if this is not a move, consider it a click and start the activity to see the posts
if(clickDuration < MAX_CLICK_DURATION) {
Intent activityStart = new Intent(getApplicationContext(), MainActivity.class);
activityStart.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(activityStart);
}
return true;
case MotionEvent.ACTION_MOVE:
params.x = initialX + (int) (event.getRawX() - initialTouchX);
params.y = initialY + (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(textView, params);
return true;
}
return false;
}
});
} catch (Exception e) {
// TODO: handle exception
}
rightLowerButton = new FloatingActionButton.Builder(this)
.setContentView(textView)
.setSystemOverlay(true)
.setLayoutParams(params)
.build();
}
#Override
public int onStartCommand( Intent intent , int flags , int startId ) {
super.onStartCommand(intent, flags, startId);
return START_REDELIVER_INTENT;
}
#Override
public void onDestroy() {
super.onDestroy();
if (textView != null) windowManager.removeView(textView);
floatingInstance = null;
}
//called to update the number on this ChatHead
public void updateUnreadNum(int unreadPosts){
if (null != textView) {
Log.d("Reddit2Go", "number of posts is: " + unreadPosts);
textView.setText(""+unreadPosts);
}
}
//called to update the list of available networks and the number on this ChatHead
public void updateUnreadNum(int unreadPosts, String networkList){
if (null != textView) {
Log.d("Reddit2Go", "number of posts is: " + unreadPosts);
//textView.setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
textView.setGravity(Gravity.CENTER);
textView.setText(""+unreadPosts+" Cached\n" + networkList);
}
}
//get a reference to a running instance of this service
public static FloatService getFloatingInstance(){
return floatingInstance;
}
}
Hi i am create a window manager pop as.
package com.appkart.callrecorder.receiver;
import java.util.List;
import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import com.appkart.callrecorder.R;
public class RecordingButtonService extends Service {
private static final String TAG = RecordingButtonService.class
.getSimpleName();
private WindowManager windowManager;
private LinearLayout chatHead;
private boolean isRecording;
#Override
public IBinder onBind(Intent intent) {
// Not used
return null;
}
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
chatHead = new LinearLayout(this);
chatHead.setBackgroundColor(RecordingButtonService.this.getResources()
.getColor(R.color.gray));
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT, 130,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.CENTER;
params.x = 0;
params.y = 0;
windowManager.addView(chatHead, params);
chatHead.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!isRecording) {
// chatHead.setImageResource(R.drawable.pause);
isRecording = true;
} else {
// chatHead.setImageResource(R.drawable.ic_launcher);
isRecording = false;
}
return true;
}
return false;
}
});
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null)
windowManager.removeView(chatHead);
}
}
It works perfectly but my requirement is little bit different.
Requirement
When start outgoing call then we add this pop window on dialer (caller/current) screen but when user pressed back then it continue display pop window while at the time user start using another app or going to home screen.I want to hide this pop window when user leave caller screen and again when user open caller screen, pop window should display.
I know we can remove pop window by
windowManager.removeView(chatHead);
but i are not getting event when user leave caller screen i.e How to know what is the current screen is display in android app.
Please advice.
I am android developer .I create system window overlay .I want to bounce bubble only stay left top corner, right top corner,bottom left corner.bottom right corner .you stretch ball from top right corner to center then ball direct bounce top right corner .ball just stay only four corner like Facebook messenger . i also try some days but i don't know to do this.here is my code any one please tell what is change in this code.
package com.example.bubble;
import java.io.IOException;
import java.io.InputStream;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.os.IBinder;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.RelativeLayout;
#SuppressWarnings("deprecation")
public class PlayerService extends Service
{
private static final int HIDDEN_FRACTION = 20; // Controls fraction of the tray hidden when open
private static final int MOVEMENT_REGION_FRACTION = 20; // Controls fraction of y-axis on screen within which the tray stays.
private static final int VIEW_CROP_FRACTION = 12; // Controls fraction of the tray chipped at the right end.
private static final int ANIMATION_FRAME_RATE = 30; // Animation frame rate per second.
private static final int VIEW_DIM_X_DP = 170; // Width of the tray in dps
private static final int VIEW_DIM_Y_DP = 170; // Height of the tray in dps
// Layout containers for various widgets
private WindowManager mWindowManager; // Reference to the window
private WindowManager.LayoutParams mWindowParams; // Parameters of the root layout
private RelativeLayout mRootLayout; // Root layout
private RelativeLayout mCoverLayout; // Contains album cover of the active song
// Variables that control drag
private int mStartDragX;
//private int mStartDragY; // Unused as yet
private int mPrevDragX;
private int mPrevDragY;
private boolean mIsTrayOpen = true;
// Controls for animations
private Timer mTrayAnimationTimer;
private TrayAnimationTimerTask mTrayTimerTask;
private Handler mAnimationHandler = new Handler();
#Override
public IBinder onBind(Intent intent) {
// Not used
return null;
}
#Override
public void onCreate() {
// Get references to all the views and add them to root view as needed.
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mRootLayout = (RelativeLayout) LayoutInflater.from(this).
inflate(R.layout.service_player, null);
mCoverLayout = (RelativeLayout) mRootLayout.findViewById(R.id.cover_layout);
mCoverLayout.setOnTouchListener(new TrayTouchListener());
mWindowParams = new WindowManager.LayoutParams(
Utils.dpToPixels(VIEW_DIM_X_DP, getResources()),
Utils.dpToPixels(VIEW_DIM_Y_DP, getResources()),
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;
mWindowManager.addView(mRootLayout, mWindowParams);
// Post these actions at the end of looper message queue so that the layout is
// fully inflated once these functions execute
mRootLayout.postDelayed(new Runnable() {
#Override
public void run() {
// Reusable variables
RelativeLayout.LayoutParams params;
InputStream is;
Bitmap bmap;
int containerNewWidth = (VIEW_CROP_FRACTION-1)*mCoverLayout.getHeight()/VIEW_CROP_FRACTION;
// Setup background album cover
is=null;
try {
//is = getAssets().open(mPlaylist.getCurrentSongInfo().mAlbumCoverPath);
is=getAssets().open("adele.png");
} catch (IOException e) {
e.printStackTrace();
}
bmap = Utils.loadMaskedBitmap(is, mCoverLayout.getHeight(), containerNewWidth);
params = (RelativeLayout.LayoutParams) mCoverLayout.getLayoutParams();
params.width = (bmap.getWidth() * mCoverLayout.getHeight()) / bmap.getHeight();
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,0);
mCoverLayout.setLayoutParams(params);
mCoverLayout.requestLayout();
mCoverLayout.setBackgroundDrawable(new BitmapDrawable(getResources(), bmap));
// Setup the root layout
mWindowParams.x = -mCoverLayout.getLayoutParams().width;
mWindowParams.y = (getApplicationContext().getResources().getDisplayMetrics().heightPixels-mRootLayout.getHeight()) / 2;
mWindowManager.updateViewLayout(mRootLayout, mWindowParams);
// Make everything visible
mRootLayout.setVisibility(View.VISIBLE);
// Animate the Tray
mTrayTimerTask = new TrayAnimationTimerTask();
mTrayAnimationTimer = new Timer();
mTrayAnimationTimer.schedule(mTrayTimerTask, 0, ANIMATION_FRAME_RATE);
}
}, ANIMATION_FRAME_RATE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getBooleanExtra("stop_service", false)){
// If it's a call from the notification, stop the service.
stopSelf();
}else{
// Make the service run in foreground so that the system does not shut it down.
Intent notificationIntent = new Intent(this, PlayerService.class);
notificationIntent.putExtra("stop_service", true);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, notificationIntent, 0);
Notification notification = new Notification(
R.drawable.ic_launcher,
"Spotify tray launched",
System.currentTimeMillis());
notification.setLatestEventInfo(
this,
"Spotify tray",
"Tap to close the widget.",
pendingIntent);
startForeground(86, notification);
}
return START_STICKY;
}
// The app is closing.
#Override
public void onDestroy() {
if (mRootLayout != null)
mWindowManager.removeView(mRootLayout);
}
// Drags the tray as per touch info
private void dragTray(int action, int x, int y){
switch (action){
case MotionEvent.ACTION_DOWN:
// Cancel any currently running animations/automatic tray movements.
if (mTrayTimerTask!=null){
mTrayTimerTask.cancel();
mTrayAnimationTimer.cancel();
}
// Store the start points
mStartDragX = x;
//mStartDragY = y;
mPrevDragX = x;
mPrevDragY = y;
break;
case MotionEvent.ACTION_MOVE:
// Calculate position of the whole view according to the drag, and update layout.
float deltaX = x-mPrevDragX;
float deltaY = y-mPrevDragY;
mWindowParams.x += deltaX;
mWindowParams.y += deltaY;
mPrevDragX = x;
mPrevDragY = y;
mWindowManager.updateViewLayout(mRootLayout, mWindowParams);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// When the view is released, bring it back to "open" or "closed" state.
if ((mIsTrayOpen && (x-mStartDragX)<=0) ||
(!mIsTrayOpen && (x-mStartDragX)>=0))
mIsTrayOpen = !mIsTrayOpen;
mTrayTimerTask = new TrayAnimationTimerTask();
mTrayAnimationTimer = new Timer();
mTrayAnimationTimer.schedule(mTrayTimerTask, 0, ANIMATION_FRAME_RATE);
break;
}
}
// Listens to the touch events on the tray.
private class TrayTouchListener implements OnTouchListener {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Filter and redirect the events to dragTray()
dragTray(action, (int)event.getRawX(), (int)event.getRawY());
break;
default:
return false;
}
return true;
}
}
// Timer for animation/automatic movement of the tray.
private class TrayAnimationTimerTask extends TimerTask{
// Ultimate destination coordinates toward which the tray will move
int mDestX;
int mDestY;
public TrayAnimationTimerTask(){
// Setup destination coordinates based on the tray state.
super();
if (!mIsTrayOpen){
mDestX = -mCoverLayout.getWidth();
}else{
mDestX = -mRootLayout.getWidth()/HIDDEN_FRACTION;
}
// Keep upper edge of the widget within the upper limit of screen
int screenHeight = getResources().getDisplayMetrics().heightPixels;
mDestY = Math.max(
screenHeight/MOVEMENT_REGION_FRACTION,
mWindowParams.y);
// Keep lower edge of the widget within the lower limit of screen
mDestY = Math.min(
((MOVEMENT_REGION_FRACTION-1)*screenHeight)/MOVEMENT_REGION_FRACTION - mRootLayout.getWidth(),
mDestY);
mDestX = Math.max(mWindowParams.x,screenHeight/MOVEMENT_REGION_FRACTION);
// Keep lower edge of the widget within the lower limit of screen
mDestX = Math.min(mDestX,((MOVEMENT_REGION_FRACTION-1)*screenHeight)/MOVEMENT_REGION_FRACTION - mRootLayout.getWidth());
}
// This function is called after every frame.
#Override
public void run() {
// handler is used to run the function on main UI thread in order to
// access the layouts and UI elements.
mAnimationHandler.post(new Runnable() {
#Override
public void run() {
// Update coordinates of the tray
mWindowParams.x = (2*(mWindowParams.x-mDestX))/3 + mDestX;
mWindowParams.y = (2*(mWindowParams.y-mDestY))/3 + mDestY;
mWindowManager.updateViewLayout(mRootLayout, mWindowParams);
// Cancel animation when the destination is reached
if (Math.abs(mWindowParams.x-mDestX)<2 && Math.abs(mWindowParams.y-mDestY)<2){
TrayAnimationTimerTask.this.cancel();
mTrayAnimationTimer.cancel();
}
}
});
}
}
}
So basically i have a Fragment class where i have a ImageView, where i have not set any image yet. So i want to do this from a Dialog Box where i have list and on the click of any of the items to add the image in the Fragment where the ImageView is situated. The image is a rectangle made in a xml file. If i add it from it's class the Fragment class it works. But i need it to add it from the Dialog Box.
And i tried this all day and nothing works, all that i get is nullPointerException in the same place where i try to call the add of the image in all the way i tried.
here is the code that i have got to after i tried a lot :).
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.widget.ImageView;
public class BrickMessageBoxGreen extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.dialog_title_green);
builder.setItems(R.array.greenBricks_array,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of the selected item
Arkitektur ark = new Arkitektur();
ImageView img = (ImageView)ark.getView().findViewById(R.id.green_brick);
ark.addGreenBrick(img);
}
});
return builder.create();
}
}
And here is the class where i have the ImageView:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.DragEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
public class Arkitektur extends Fragment implements OnTouchListener, OnDragListener {
private int _xDelta;
private int _yDelta;
ViewGroup _root;
private View arkitektur;
ImageView greenBrick;
ImageView redBrick;
ImageView yellowBrick;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
arkitektur = inflater.inflate(R.layout.arkitektur, container, false);
//arkitektur.findViewById(R.id.green_brick).setOnTouchListener(this);
//greenBrick = (ImageView) arkitektur.findViewById(R.id.green_brick);
//arkitektur.findViewById(R.id.root).setOnDragListener(this);
//arkitektur.findViewById(R.id.bottom_container).setOnDragListener(this);
//addGreenBrick();
_root = (ViewGroup) arkitektur.findViewById(R.id.root);
_root.setOnDragListener(this);
return arkitektur;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX()*2;
final int Y = (int) event.getRawY()*2;
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;
}
#Override
public boolean onDrag(View v, DragEvent e) {
if (e.getAction()==DragEvent.ACTION_DROP) {
View view = (View) e.getLocalState();
ViewGroup from = (ViewGroup) view.getParent();
from.removeView(view);
LinearLayout to = (LinearLayout) v;
to.addView(view);
view.setVisibility(View.VISIBLE);
}
return true;
}
public void addGreenBrick(View v)
{
v.findViewById(R.id.green_brick).setOnTouchListener(this);
greenBrick = (ImageView) v.findViewById(R.id.green_brick);
greenBrick.setImageResource(R.drawable.green_brick);
}
}
Thanks!
I agree with Tamilselvan Kalimuthu, just let your fragment implement a listener and set it as an attribute of BrickMessageBoxGreen class.
Edit:
Added some code to clarify the idea.
BrickMessageBoxGreen class:
public OnClickDialogListener listener //Attribute of your class
public void setDialogListener(OnClickDialogListener l){ //Setting the listener
this.listener = l;
}
new DialogInterface.OnClickListener() { //Changing onClick method
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of the selected item
this.listener.onDialogClicked("green");
}
});
Arkitektur class:
public interface OnClickDialogListener { //Your listener definition, you could place it elsewhere
void onDialogClicked(String colorName);
}
public class Arkitektur extends Fragment implements OnTouchListener, OnDragListener, OnClickDialogListener { //Implementing your listener interface
public void onDialogClicked(String colorName){//Method implementation
if(colorName.equals("green")){
addGreenBrick();
}else if(colorName.equals("red")){
addRedBrick();
}else if(colorName.equals("yellor")){
addYellowBrick();
}
}