I am making an application by using page curl for that am using this link:-
https://github.com/harism/android_page_curl.
In that link implementing page curl using bitmap.But My requirement is that curl to View ,for that I convert
View(LinearLayout) into bitmap and set onclicklistener on child view, for more clarification please see
attached image
My code is as:-
public static LinearLayout createProgrammeView(final Context context,
int width, int height, String title, String time) {
// Upper layout of screen
LinearLayout objmainlayout = new LinearLayout(context);
if (height >= 320) {
objmainlayout.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT, (height -100)));
Log.e("chectttttttttttlayout",""+(height-71));
} else {
objmainlayout.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT, (height - 90)));
}
objmainlayout.setBackgroundColor(Color.WHITE);
objmainlayout.setOrientation(LinearLayout.VERTICAL);
objmainlayout.setPadding(10, 0, 10,0);
for (int mindex = 0; mindex <3; mindex++)
{
RelativeLayout.LayoutParams objparams;
// Layout Root View (RelativeLayout)
RelativeLayout objrelativeinnerlayout = new RelativeLayout(context);
if (height >= 320)
{
objparams = new RelativeLayout.LayoutParams(width-20,
((height - 71) / 3) - 10);
Log.e("chectt33333tlayout",""+(((height - 71) / 3) - 10));
} else {
objparams = new RelativeLayout.LayoutParams(width,
((height - 90) / 3) - 10);
}
//objparams.topMargin=10;
objrelativeinnerlayout.setLayoutParams(objparams);
// rlv.setBackgroundResource(R.drawable.sss);
// rlv.setBackgroundResource(R.drawable.sss);
ImageView objrow1img1 = new ImageView(context);
if (height >= 320) {
objrow1img1.setLayoutParams(new RelativeLayout.LayoutParams(
(width - 30) / 2,((height - 71) / 3) - 10));
}
objrow1img1.setScaleType(ScaleType.FIT_XY);
RelativeLayout.LayoutParams objlp = (RelativeLayout.LayoutParams) objrow1img1.getLayoutParams();
objlp.topMargin=10;
objlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
objrow1img1.setId(1);
objrow1img1.setBackgroundColor(Color.RED);
if (mindex == 0) {
objrow1img1.setImageResource(R.drawable.fblogin);
objrow1img1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context,"onclick",Toast.LENGTH_LONG).show();
Log.e("check click","good");
//Intent objIntent = new Intent(context,
//FacebookAlbumList.class);
//objcoContext.startActivity(objIntent);
}
});
}
else {/*
if (data != null
&& data.size() > saveindex
&& data.get(saveindex) != null
&& data.get(saveindex).get(0) != null
&& data.get(saveindex).get(0).getImagepath() != null) {
objrow1img1.setVisibility(View.VISIBLE);
System.gc();
decodeBitMap(data.get(index).get(0).getImagepath(),
objrow1img1);
} else {
objrow1img1.setVisibility(View.INVISIBLE);
}
*/}
objrelativeinnerlayout.addView(objrow1img1);
ImageView objrow1img2 = new ImageView(context);
objrow1img2.setLayoutParams(new RelativeLayout.LayoutParams(
(width - 30) / 2,((height - 71) / 3) - 10));
objrow1img2.setScaleType(ScaleType.FIT_XY);
objrow1img2.setBackgroundColor(Color.RED);
RelativeLayout.LayoutParams objlrelativelayoutparam = (RelativeLayout.LayoutParams) objrow1img2
.getLayoutParams();
objlrelativelayoutparam.setMargins(10, 10, 0, 0);
objlrelativelayoutparam.addRule(RelativeLayout.RIGHT_OF,1);
objrelativeinnerlayout.addView(objrow1img2);
objmainlayout.addView(objrelativeinnerlayout);
}
return objmainlayout;
}
public static Bitmap loadBitmapFromView(LinearLayout v) {
v.measure(MeasureSpec.makeMeasureSpec(v.getLayoutParams().width,
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
v.getLayoutParams().height, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(),
Bitmap.Config.RGB_565);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
Here I put code of Myview and converting it into bitmap.Problem is that How I can get onclickListener on that?
Please anyone suggest me thanks in advance.
I ran into a similar problem and. To get it working I have a parent layout (contentContainer) which contains 2 subviews:
Content view which is converted to bitmap when curling
CurlView (OpenGL Surface)
I had to set an onClickListener to the parent layout to catch the events and send or not send them to the CurlView. When the events are sent to the CurlView, the CurlView is brought to front (using bringToFront() method). Otherwise, the content view is brought to front.
To decide if events are sent or not to the CurlView I use a method that returns true if the tap was within the page curl area (aprox. 1/6 of the screen, both sides). Additionally I have a gesture and scale detectors to detect singleTap and longPress, which is what we need for user interaction. When a singleTap or longPress is catched, the postion (x,y) tells me where the user touched so I can launch some activity, show a context menu or whatever.
Some sample code:
contentContainer.setOnClickListener(null); // DO NOT REMOVE THIS, IT'S A WORKAROUND
contentContainer.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
mScaleDetector.onTouchEvent(event);
int x = (int)event.getX();
int y = (int)event.getY();
boolean isMoving = event.getAction() == MotionEvent.ACTION_MOVE;
boolean isTouchDown = event.getAction() == MotionEvent.ACTION_DOWN;
boolean isTouchUp = event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL;
boolean pageCurlArea = isPageCurlArea(x, y);
boolean sendEventToCurlView = false;
if (isTouchDown && pageCurlArea) {
downInPageArea = true;
sendEventToCurlView = true;
} else if (downInPageArea && isMoving) {
sendEventToCurlView = true;
} else if (downInPageArea && isTouchUp) {
downInPageArea = false;
sendEventToCurlView = true;
} else if (!downInPageArea && isMoving) {
return false;
}
if (downInPageArea && isMoving && !curlViewIsOnTop) {
bringCurlViewToFront();
}
if (sendEventToCurlView) {
MotionEvent mEvent = MotionEvent.obtain(event);
mCurlView.onTouch(v, mEvent);
}
return !sendEventToCurlView;
}
});
It is a work in progress yet, because I need to modify it to not use "page curl area" to discriminate between "curl event" and other events (singleTap, longPress...), for which I plan to use both the gesture and scale detectors to return if an event was catched and depending on the result, continue sending the event to the CurlView or not. This is necessary to perform "taps" and "longPress" within the 1/6 page curl area.
Hope it helps.
Related
This question already has answers here:
SYSTEM_ALERT_WINDOW PERMISSION on API 26 not working as expected. Permission denied for window type 2002
(6 answers)
Closed 3 years ago.
I was working in Floating Widget service icon ,the code is working fine till android version 6.1,i am able to get the notification icon from the server when it send the notification.
but while testing it in android version 8.1 the application getting crushed when the notification is send from the server,
but i am not able to find the solution for it.i dont have any idea why it is happening.
LOGCAT
beginning of crash
2019-03-02 11:41:21.416 12616-12616/com.progressive_solution.parttimeforce E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.progressive_solution.parttimeforce, PID: 12616
java.lang.RuntimeException: Unable to create service com.progressive_solution.parttimeforce.FloatingWidgetService: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W#ac5309 -- permission denied for window type 2002
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3568)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1812)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W#ac5309 -- permission denied for window type 2002
at android.view.ViewRootImpl.setView(ViewRootImpl.java:1026)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:384)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:101)
at com.progressive_solution.parttimeforce.FloatingWidgetService.addRemoveView(FloatingWidgetService.java:86)
at com.progressive_solution.parttimeforce.FloatingWidgetService.onCreate(FloatingWidgetService.java:58)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3558)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1812)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
MYCODE
FloatingWidgetService.java
public class FloatingWidgetService extends Service implements View.OnClickListener
{
private WindowManager mWindowManager;
private View mFloatingWidgetView, collapsedView, expandedView;
private ImageView remove_image_view;
private Point szWindow = new Point();
private View removeFloatingWidgetView;
private int x_init_cord, y_init_cord, x_init_margin, y_init_margin;
//Variable to check if the Floating widget view is on left side or in right side
// initially we are displaying Floating widget view to Left side so set it to true
private boolean isLeft = true;
public FloatingWidgetService() {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
//init WindowManager
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
getWindowManagerDefaultDisplay();
//Init LayoutInflater
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
addRemoveView(inflater);
addFloatingWidgetView(inflater);
implementClickListeners();
implementTouchListenerToFloatingWidgetView();
}
/* Add Remove View to Window Manager */
private View addRemoveView(LayoutInflater inflater) {
//Inflate the removing view layout we created
removeFloatingWidgetView = inflater.inflate(R.layout.remove_floating_widget_layout, null);
//Add the view to the window.
WindowManager.LayoutParams paramRemove = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
//Specify the view position
paramRemove.gravity = Gravity.TOP | Gravity.LEFT;
//Initially the Removing widget view is not visible, so set visibility to GONE
removeFloatingWidgetView.setVisibility(View.GONE);
remove_image_view = (ImageView) removeFloatingWidgetView.findViewById(R.id.remove_img);
//Add the view to the window
mWindowManager.addView(removeFloatingWidgetView, paramRemove);
return remove_image_view;
}
/* Add Floating Widget View to Window Manager */
private void addFloatingWidgetView(LayoutInflater inflater) {
//Inflate the floating view layout we created
mFloatingWidgetView = inflater.inflate(R.layout.activity_floating_widget_service, null);
//Add the view to the window.
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);
//Specify the view position
params.gravity = Gravity.TOP | Gravity.LEFT;
//Initially view will be added to top-left corner, you change x-y coordinates according to your need
params.x = 0;
params.y = 100;
//Add the view to the window
mWindowManager.addView(mFloatingWidgetView, params);
//find id of collapsed view layout
collapsedView = mFloatingWidgetView.findViewById(R.id.collapse_view);
//find id of the expanded view layout
expandedView = mFloatingWidgetView.findViewById(R.id.expanded_container);
}
private void getWindowManagerDefaultDisplay() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
mWindowManager.getDefaultDisplay().getSize(szWindow);
else {
int w = mWindowManager.getDefaultDisplay().getWidth();
int h = mWindowManager.getDefaultDisplay().getHeight();
szWindow.set(w, h);
}
}
/* Implement Touch Listener to Floating Widget Root View */
private void implementTouchListenerToFloatingWidgetView() {
//Drag and move floating view using user's touch action.
mFloatingWidgetView.findViewById(R.id.root_container).setOnTouchListener(new View.OnTouchListener() {
long time_start = 0, time_end = 0;
boolean isLongClick = false;//variable to judge if user click long press
boolean inBounded = false;//variable to judge if floating view is bounded to remove view
int remove_img_width = 0, remove_img_height = 0;
Handler handler_longClick = new Handler();
Runnable runnable_longClick = new Runnable() {
#Override
public void run() {
//On Floating Widget Long Click
//Set isLongClick as true
isLongClick = true;
//Set remove widget view visibility to VISIBLE
removeFloatingWidgetView.setVisibility(View.VISIBLE);
onFloatingWidgetLongClick();
}
};
#Override
public boolean onTouch(View v, MotionEvent event) {
//Get Floating widget view params
WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) mFloatingWidgetView.getLayoutParams();
//get the touch location coordinates
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
int x_cord_Destination, y_cord_Destination;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
time_start = System.currentTimeMillis();
handler_longClick.postDelayed(runnable_longClick, 600);
remove_img_width = remove_image_view.getLayoutParams().width;
remove_img_height = remove_image_view.getLayoutParams().height;
x_init_cord = x_cord;
y_init_cord = y_cord;
//remember the initial position.
x_init_margin = layoutParams.x;
y_init_margin = layoutParams.y;
return true;
case MotionEvent.ACTION_UP:
isLongClick = false;
removeFloatingWidgetView.setVisibility(View.GONE);
remove_image_view.getLayoutParams().height = remove_img_height;
remove_image_view.getLayoutParams().width = remove_img_width;
handler_longClick.removeCallbacks(runnable_longClick);
//If user drag and drop the floating widget view into remove view then stop the service
if (inBounded) {
stopSelf();
inBounded = false;
break;
}
//Get the difference between initial coordinate and current coordinate
int x_diff = x_cord - x_init_cord;
int y_diff = y_cord - y_init_cord;
//The check for x_diff <5 && y_diff< 5 because sometime elements moves a little while clicking.
//So that is click event.
if (Math.abs(x_diff) < 5 && Math.abs(y_diff) < 5) {
time_end = System.currentTimeMillis();
//Also check the difference between start time and end time should be less than 300ms
if ((time_end - time_start) < 300)
onFloatingWidgetClick();
}
y_cord_Destination = y_init_margin + y_diff;
int barHeight = getStatusBarHeight();
if (y_cord_Destination < 0) {
y_cord_Destination = 0;
} else if (y_cord_Destination + (mFloatingWidgetView.getHeight() + barHeight) > szWindow.y) {
y_cord_Destination = szWindow.y - (mFloatingWidgetView.getHeight() + barHeight);
}
layoutParams.y = y_cord_Destination;
inBounded = false;
//reset position if user drags the floating view
resetPosition(x_cord);
return true;
case MotionEvent.ACTION_MOVE:
int x_diff_move = x_cord - x_init_cord;
int y_diff_move = y_cord - y_init_cord;
x_cord_Destination = x_init_margin + x_diff_move;
y_cord_Destination = y_init_margin + y_diff_move;
//If user long click the floating view, update remove view
if (isLongClick) {
int x_bound_left = szWindow.x / 2 - (int) (remove_img_width * 1.5);
int x_bound_right = szWindow.x / 2 + (int) (remove_img_width * 1.5);
int y_bound_top = szWindow.y - (int) (remove_img_height * 1.5);
//If Floating view comes under Remove View update Window Manager
if ((x_cord >= x_bound_left && x_cord <= x_bound_right) && y_cord >= y_bound_top) {
inBounded = true;
int x_cord_remove = (int) ((szWindow.x - (remove_img_height * 1.5)) / 2);
int y_cord_remove = (int) (szWindow.y - ((remove_img_width * 1.5) + getStatusBarHeight()));
if (remove_image_view.getLayoutParams().height == remove_img_height) {
remove_image_view.getLayoutParams().height = (int) (remove_img_height * 1.5);
remove_image_view.getLayoutParams().width = (int) (remove_img_width * 1.5);
WindowManager.LayoutParams param_remove = (WindowManager.LayoutParams) removeFloatingWidgetView.getLayoutParams();
param_remove.x = x_cord_remove;
param_remove.y = y_cord_remove;
mWindowManager.updateViewLayout(removeFloatingWidgetView, param_remove);
}
layoutParams.x = x_cord_remove + (Math.abs(removeFloatingWidgetView.getWidth() - mFloatingWidgetView.getWidth())) / 2;
layoutParams.y = y_cord_remove + (Math.abs(removeFloatingWidgetView.getHeight() - mFloatingWidgetView.getHeight())) / 2;
//Update the layout with new X & Y coordinate
mWindowManager.updateViewLayout(mFloatingWidgetView, layoutParams);
break;
} else {
//If Floating window gets out of the Remove view update Remove view again
inBounded = false;
remove_image_view.getLayoutParams().height = remove_img_height;
remove_image_view.getLayoutParams().width = remove_img_width;
onFloatingWidgetClick();
}
}
layoutParams.x = x_cord_Destination;
layoutParams.y = y_cord_Destination;
//Update the layout with new X & Y coordinate
mWindowManager.updateViewLayout(mFloatingWidgetView, layoutParams);
return true;
}
return false;
}
});
}
private void implementClickListeners() {
mFloatingWidgetView.findViewById(R.id.close_floating_view).setOnClickListener(this);
mFloatingWidgetView.findViewById(R.id.close_expanded_view).setOnClickListener(this);
mFloatingWidgetView.findViewById(R.id.open_activity_button).setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.close_floating_view:
//close the service and remove the from from the window
stopSelf();
break;
case R.id.close_expanded_view:
collapsedView.setVisibility(View.VISIBLE);
expandedView.setVisibility(View.GONE);
break;
case R.id.open_activity_button:
//open the activity and stop service
Intent intent = new Intent(FloatingWidgetService.this, Get_Permission.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
//close the service and remove view from the view hierarchy
stopSelf();
break;
}
}
/* on Floating Widget Long Click, increase the size of remove view as it look like taking focus */
private void onFloatingWidgetLongClick() {
//Get remove Floating view params
WindowManager.LayoutParams removeParams = (WindowManager.LayoutParams) removeFloatingWidgetView.getLayoutParams();
//get x and y coordinates of remove view
int x_cord = (szWindow.x - removeFloatingWidgetView.getWidth()) / 2;
int y_cord = szWindow.y - (removeFloatingWidgetView.getHeight() + getStatusBarHeight());
removeParams.x = x_cord;
removeParams.y = y_cord;
//Update Remove view params
mWindowManager.updateViewLayout(removeFloatingWidgetView, removeParams);
}
/* Reset position of Floating Widget view on dragging */
private void resetPosition(int x_cord_now) {
if (x_cord_now <= szWindow.x / 2) {
isLeft = true;
moveToLeft(x_cord_now);
} else {
isLeft = false;
moveToRight(x_cord_now);
}
}
/* Method to move the Floating widget view to Left */
private void moveToLeft(final int current_x_cord) {
final int x = szWindow.x - current_x_cord;
new CountDownTimer(500, 5) {
//get params of Floating Widget view
WindowManager.LayoutParams mParams = (WindowManager.LayoutParams) mFloatingWidgetView.getLayoutParams();
public void onTick(long t) {
long step = (500 - t) / 5;
mParams.x = 0 - (int) (current_x_cord * current_x_cord * step);
//If you want bounce effect uncomment below line and comment above line
// mParams.x = 0 - (int) (double) bounceValue(step, x);
//Update window manager for Floating Widget
mWindowManager.updateViewLayout(mFloatingWidgetView, mParams);
}
public void onFinish() {
mParams.x = 0;
//Update window manager for Floating Widget
mWindowManager.updateViewLayout(mFloatingWidgetView, mParams);
}
}.start();
}
/* Method to move the Floating widget view to Right */
private void moveToRight(final int current_x_cord) {
new CountDownTimer(500, 5) {
//get params of Floating Widget view
WindowManager.LayoutParams mParams = (WindowManager.LayoutParams) mFloatingWidgetView.getLayoutParams();
public void onTick(long t) {
long step = (500 - t) / 5;
mParams.x = (int) (szWindow.x + (current_x_cord * current_x_cord * step) - mFloatingWidgetView.getWidth());
//If you want bounce effect uncomment below line and comment above line
// mParams.x = szWindow.x + (int) (double) bounceValue(step, x_cord_now) - mFloatingWidgetView.getWidth();
//Update window manager for Floating Widget
mWindowManager.updateViewLayout(mFloatingWidgetView, mParams);
}
public void onFinish() {
mParams.x = szWindow.x - mFloatingWidgetView.getWidth();
//Update window manager for Floating Widget
mWindowManager.updateViewLayout(mFloatingWidgetView, mParams);
}
}.start();
}
/* Get Bounce value if you want to make bounce effect to your Floating Widget */
private double bounceValue(long step, long scale) {
double value = scale * java.lang.Math.exp(-0.055 * step) * java.lang.Math.cos(0.08 * step);
return value;
}
/* Detect if the floating view is collapsed or expanded */
private boolean isViewCollapsed() {
return mFloatingWidgetView == null || mFloatingWidgetView.findViewById(R.id.collapse_view).getVisibility() == View.VISIBLE;
}
/* return status bar height on basis of device display metrics */
private int getStatusBarHeight() {
return (int) Math.ceil(25 * getApplicationContext().getResources().getDisplayMetrics().density);
}
/* Update Floating Widget view coordinates on Configuration change */
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getWindowManagerDefaultDisplay();
WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) mFloatingWidgetView.getLayoutParams();
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (layoutParams.y + (mFloatingWidgetView.getHeight() + getStatusBarHeight()) > szWindow.y) {
layoutParams.y = szWindow.y - (mFloatingWidgetView.getHeight() + getStatusBarHeight());
mWindowManager.updateViewLayout(mFloatingWidgetView, layoutParams);
}
if (layoutParams.x != 0 && layoutParams.x < szWindow.x) {
resetPosition(szWindow.x);
}
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
if (layoutParams.x > szWindow.x) {
resetPosition(szWindow.x);
}
}
}
/* on Floating widget click show expanded view */
private void onFloatingWidgetClick() {
if (isViewCollapsed()) {
//When user clicks on the image view of the collapsed layout,
//visibility of the collapsed layout will be changed to "View.GONE"
//and expanded view will become visible.
collapsedView.setVisibility(View.GONE);
expandedView.setVisibility(View.VISIBLE);
}
}
#Override
public void onDestroy() {
super.onDestroy();
/* on destroy remove both view from window manager */
if (mFloatingWidgetView != null)
mWindowManager.removeView(mFloatingWidgetView);
if (removeFloatingWidgetView != null)
mWindowManager.removeView(removeFloatingWidgetView);
}
}
Permissioncheck.java
private void writeCalendarEvent()
{
Log.d(Utils.LogTag, "lst_StartService -> Utils.canDrawOverlays(Main.this): " + Utils.canDrawOverlays(Permissioncheck.this));
if(Utils.canDrawOverlays(Permissioncheck.this))
{
checkPermission_Contact();
startService();
}
else
{
requestPermission(OVERLAY_PERMISSION_REQ_CODE_CHATHEAD);
}
}
public void startService()
{
boolean results = checkPermission_Contact();
if (results)
{
Intent k = new Intent(context, Login.class);
startActivity(k);
}
}
private void needPermissionDialog(final int requestCode)
{
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(Permissioncheck.this);
builder.setMessage("You need to allow permission");
builder.setPositiveButton("OK",
new android.content.DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
// TODO Auto-generated method stub
requestPermission(requestCode);
}
});
builder.setNegativeButton("Cancel", new android.content.DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
// TODO Auto-generated method stub
}
});
builder.setCancelable(false);
builder.show();
}
#Override
protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
}
private void requestPermission(int requestCode)
{
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, requestCode);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == OVERLAY_PERMISSION_REQ_CODE_CHATHEAD)
{
if (!Utils.canDrawOverlays(Permissioncheck.this))
{
needPermissionDialog(requestCode);
} else
{
startService();
}
}
}
Help me to fix the problem.
add WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
reference
I am Working on Android cocos 2d and i have 8-10 CCSprites which has to scroll horizontally by click of each sprite their is next CCLayer to load so need to Add ScrollView in CCLayer but i am not getting how to do this i am using cocos2d-android.jar
i am using this code but not working :-
final Activity mActivity=CCDirector.sharedDirector().getActivity();
final View view= LayoutInflater.from(mActivity).inflate(R.layout.level_scroll,null);
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
mActivity.addContentView(view, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
});
This is the layer to which you have to add all sprites:
public class ItemScrollLayer extends CCLayer{
ArrayList<ExtraProjectileData> spirtes;
float scaleX,scaleY;
public ItemScrollLayer(float scaleX,float scaleY,ArrayList<ExtraProjectileData> sprites,float screensize)
{
this.scaleX = scaleX;
this.scaleY = scaleY;
this.spirtes = sprites;
float horizontal_distance = 140*scaleX;
for(int i = 0;i<sprites.size();i++)
{
CCSprite indi_sprite = sprites.get(i).getProjectile();
indi_sprite.setScale(GameActivity.aspect_Scale(indi_sprite, scaleX, scaleY));
indi_sprite.setPosition(horizontal_distance+(i*screensize),150*scaleY);
addChild(indi_sprite);
}
}
}
the code to move layer placed in on Touch of my MainLayer:
#Override
public boolean ccTouchesMoved(MotionEvent event)
{
System.out.println("Touches Moved Called for UpgradeMenu");
CGPoint LocationMoved = CCDirector.sharedDirector().convertToGL(CGPoint.make(event.getX(), event.getY()));
float difference = LocationMoved.x - PrevTouchLocation.x;
float posX = scroll_layer.getPosition().x + difference;
scroll_layer.setPosition(CGPoint.make(posX, 0));
if(posX > 0){
scroll_layer.setPosition(CGPoint.zero());
}
else if(posX < (-size.width)*(sprites.size()-1)){
System.out.println("Right Limit Exceeded");
scroll_layer.setPosition((-size.width)*(sprites.size()-1),0);
}
if(difference < -5*GameActivity.VEL_FACTOR){
direction = -1;
}
else if(difference > 5*GameActivity.VEL_FACTOR){
direction = 1;
}
PrevTouchLocation = LocationMoved;
return true;
}
#Override
public boolean ccTouchesEnded(MotionEvent event)
{
endLocation = CCDirector.sharedDirector().convertToGL(CGPoint.make(event.getX(), event.getY()));
if(!moving)
{
float total = startLocation.x-endLocation.x;
if(direction == 1 && !(counter <=0))
{
CGPoint move_pos = CGPoint.make(size.width+total, 0);
CCMoveBy go_left = CCMoveBy.action(0.5f, move_pos);
CCCallFuncN regulator = CCCallFuncN.action(this, "regulator");
CCSequence seq = CCSequence.actions(go_left, regulator);
moving = true;
scroll_layer.runAction(seq);
counter--;
projectilePriceLabel.setString(getCurrentPrice());
}
else if(direction == -1 && !(counter >= sprites.size()-1))
{
CGPoint move_pos = CGPoint.make(-size.width+total, 0);
CCMoveBy go_right = CCMoveBy.action(0.5f, move_pos);
CCCallFuncN regulator = CCCallFuncN.action(this, "regulator");
CCSequence seq = CCSequence.actions(go_right, regulator);
moving = true;
scroll_layer.runAction(seq);
counter++;
projectilePriceLabel.setString(getCurrentPrice());
}
}
PrevTouchLocation = CGPoint.zero();
return true;
}
you can edit as per your requirement
Check this, its for vertical scrolling. You just need to change little to achieve.
https://stackoverflow.com/a/12056450/1614340
Let me know if you can't get any idea from this I will provide code.
You can do by adding all sprites to a parent layer then move this parent layer by using MoveBy modifier in ccTouchesMoved
sorry for delay. You have to initialize PrevTouchLocation before you use that as mention below.
CGPoint PrevTouchLocation = CGPoint.zero();
i use this code for displays two view mRenderSurfaceView and gestureOverlayView:
relativeLayout = new RelativeLayout(this);
final FrameLayout.LayoutParams relativeLayoutLayoutParams = new FrameLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT , RelativeLayout.LayoutParams.FILL_PARENT );
gestureOverlayView = new GestureOverlayView(this);
gestureOverlayView.setEnabled(true);
this.mRenderSurfaceView = new RenderSurfaceView(this);
this.mRenderSurfaceView.setRenderer(mEngine);
surfaceViewLayoutParams = new RelativeLayout.LayoutParams(super.createSurfaceViewLayoutParams());
gestureOverlayView.addOnGesturePerformedListener(this);
relativeLayout.addView(this.mRenderSurfaceView, surfaceViewLayoutParams);
relativeLayout.addView(gestureOverlayView, 1248,1152);
gestureOverlayView.setVisibility(View.GONE);
this.setContentView(relativeLayout, relativeLayoutLayoutParams);
i drawn with this:
#Override
public boolean onTouch(View v, MotionEvent paramMotionEvent) {
//TODO Auto-generated method stub
if(paramMotionEvent.getAction() == MotionEvent.ACTION_DOWN) {
isDrawing = true;
}
//TouchEvent
if(paramMotionEvent.getAction() == MotionEvent.ACTION_UP) {
isDrawing = false;
rec = new Rectangle[250];
Arrays.fill( rec, null );
irec=0;
}
if (isDrawing = true) {
if (rec[249]!=null){
return false;
}
rec[irec] = new Rectangle(paramMotionEvent.getX(), paramMotionEvent.getY(), 1, 1);
if (irec != 0) {
Line l = new Line(rec[irec-1].getX(), rec[irec-1].getY(), rec[irec].getX(), rec[irec].getY());
l.setColor(0.5f, 1f, 0.3f);
mScene.attachChild(l);
}
irec++;
}
return true;
}
and in OnloadScene i this gestureOverlayView.setOnTouchListener(this);
my Scene do 1248*1152, the problem is public boolean onTouch works fine if i in up left but if move down in scene or right the drawn is shift. how make a view with good Width and height (I guess that is the problem, this keep camera ratio) ?
if i use mScene.setOnSceneTouchListener the drawn is ok but the gesture don't work ...
Solved by velocityOnScreenControl.attachChild(l); of (private AnalogOnScreenControl velocityOnScreenControl;) Use AnalogOnScreenControl example.
To understand this question, first read how this method works.
I am trying to implements a drag and drop ListView, it's going alright but have run into
a road block. So I don't have to handled everything, I am intercepting(but returning false) MotionEvents sent to the ListView, letting it handle scrolling and stuff. When I want to start dragging a item, I then return true and handled all the dragging stuff. Everything is working fine except for one thing. The drag(drag and drop) is started when it is determined that a long press as a occurred(in onInterceptTouchEvent). I get the Bitmap for the image that I drag around like so. itemPositition being the index of the item that was selected.
(omitting irrelevant parts)
...
View dragItem = mListView.getChildAt(itemPosition);
dragItem.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(dragItem.getDrawingCache());
mDragImage = new ImageView(mContext);
mDragImage.setImageBitmap(bitmap);
...
The problem is, mDragImage is a solid black like this.
But, if I don't let ListView handle anything. As in, I start the drag on ACTION_DOWN and stop on ACTION_UP, mDragImage looks has expected(but I obviously lose scrolling abilities).
Since the drag is started with a long press, the ListView is given the opportunity to do things before the long press occurs. This is my guess as to why this is happening. When a item is pressed, it is highlighted by the ListView. Somewhere in doing so, it is messing with the bitmap. So when I go to get it, it's in a weird state(all black).
I see two options for fixing this, neither of which I know how to do.
Create a image from scratch.
Handle the highlighting myself(if that is the problem).
Option two seems a better one to me, except that I looked at the documentation and the source code and could not find out how to do so. Here are some things I have done/tried.
I set setOnItemClickListener(...) and
setOnItemSelectedListener(...) with a empty method(highlighting
still happens). (Before anyone suggests it, calling
setOnClickListener results in a runtime error.)
I also looked into trying to get the ListView to make a new item
(for option 2), but could not find a way.
Spent 45ish minutes looking through the source code and
documentation trying to pinpoint where the highlighting was
happening(I never found it).
Any help fixing this would be appreciated.
(EDIT1 START)
So I don't actually know if onLongClickListener is working, I made an error before thinking it was. I am trying to set it up right now, will update when I find out if it does.
(EDIT1 END)
Last minute edit before post. I tried using onLongClickListener just now, and the image is good. I would still like to know if there is another way. How I have to use onLongClickListener to get things working is ugly, but it works. I also spent so much time trying to figure this out, it would be nice to find out the answer. I still want to be able to change/handle the highlight color, the default orangeish color is not pretty. Oh and sorry about the length of the post. I could not think of way of making it shorter, while supplying all the information I thought was needed.
use this code, it's allows operation drug and drop in ListView:
public class DraggableListView extends ListView {
private static final String LOG_TAG = "tasks365";
private static final int END_OF_LIST_POSITION = -2;
private DropListener mDropListener;
private int draggingItemHoverPosition;
private int dragStartPosition; // where was the dragged item originally
private int mUpperBound; // scroll the view when dragging point is moving out of this bound
private int mLowerBound; // scroll the view when dragging point is moving out of this bound
private int touchSlop;
private Dragging dragging;
private GestureDetector longPressDetector;
public DraggableListView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.listViewStyle);
}
public DraggableListView(final Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
longPressDetector = new GestureDetector(getContext(), new SimpleOnGestureListener() {
#Override
public void onLongPress(final MotionEvent e) {
int x = (int) e.getX();
final int y = (int) e.getY();
int itemnum = pointToPosition(x, y);
if (itemnum == AdapterView.INVALID_POSITION) {
return;
}
if (dragging != null) {
dragging.stop();
dragging = null;
}
final View item = getChildAt(itemnum - getFirstVisiblePosition());
item.setPressed(false);
dragging = new Dragging(getContext());
dragging.start(y, ((int) e.getRawY()) - y, item);
draggingItemHoverPosition = itemnum;
dragStartPosition = draggingItemHoverPosition;
int height = getHeight();
mUpperBound = Math.min(y - touchSlop, height / 3);
mLowerBound = Math.max(y + touchSlop, height * 2 / 3);
}
});
setOnItemLongClickListener(new OnItemLongClickListener() {
#SuppressWarnings("unused")
public boolean onItemLongClick(AdapterView<?> paramAdapterView, View paramView, int paramInt, long paramLong) {
// Return true to let AbsListView reset touch mode
// Without this handler, the pressed item will keep highlight.
return true;
}
});
}
/* pointToPosition() doesn't consider invisible views, but we need to, so implement a slightly different version. */
private int myPointToPosition(int x, int y) {
if (y < 0) {
return getFirstVisiblePosition();
}
Rect frame = new Rect();
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
child.getHitRect(frame);
if (frame.contains(x, y)) {
return getFirstVisiblePosition() + i;
}
}
if ((x >= frame.left) && (x < frame.right) && (y >= frame.bottom)) {
return END_OF_LIST_POSITION;
}
return INVALID_POSITION;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (longPressDetector.onTouchEvent(ev)) {
return true;
}
if ((dragging == null) || (mDropListener == null)) {
// it is not dragging, or there is no drop listener
return super.onTouchEvent(ev);
}
int action = ev.getAction();
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
dragging.stop();
dragging = null;
if (mDropListener != null) {
if (draggingItemHoverPosition == END_OF_LIST_POSITION) {
mDropListener.drop(dragStartPosition, getCount() - 1);
} else if (draggingItemHoverPosition != INVALID_POSITION) {
mDropListener.drop(dragStartPosition, draggingItemHoverPosition);
}
}
resetViews();
break;
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
int x = (int) ev.getX();
int y = (int) ev.getY();
dragging.drag(x, y);
int position = dragging.calculateHoverPosition();
if (position != INVALID_POSITION) {
if ((action == MotionEvent.ACTION_DOWN) || (position != draggingItemHoverPosition)) {
draggingItemHoverPosition = position;
doExpansion();
}
scrollList(y);
}
break;
}
return true;
}
private void doExpansion() {
int expanItemViewIndex = draggingItemHoverPosition - getFirstVisiblePosition();
if (draggingItemHoverPosition >= dragStartPosition) {
expanItemViewIndex++;
}
// Log.v(LOG_TAG, "Dragging item hovers over position " + draggingItemHoverPosition + ", expand item at index "
// + expanItemViewIndex);
View draggingItemOriginalView = getChildAt(dragStartPosition - getFirstVisiblePosition());
for (int i = 0;; i++) {
View itemView = getChildAt(i);
if (itemView == null) {
break;
}
ViewGroup.LayoutParams params = itemView.getLayoutParams();
int height = LayoutParams.WRAP_CONTENT;
if (itemView.equals(draggingItemOriginalView)) {
height = 1;
} else if (i == expanItemViewIndex) {
height = itemView.getHeight() + dragging.getDraggingItemHeight();
}
params.height = height;
itemView.setLayoutParams(params);
}
}
/**
* Reset view to original height.
*/
private void resetViews() {
for (int i = 0;; i++) {
View v = getChildAt(i);
if (v == null) {
layoutChildren(); // force children to be recreated where needed
v = getChildAt(i);
if (v == null) {
break;
}
}
ViewGroup.LayoutParams params = v.getLayoutParams();
params.height = LayoutParams.WRAP_CONTENT;
v.setLayoutParams(params);
}
}
private void resetScrollBounds(int y) {
int height = getHeight();
if (y >= height / 3) {
mUpperBound = height / 3;
}
if (y <= height * 2 / 3) {
mLowerBound = height * 2 / 3;
}
}
private void scrollList(int y) {
resetScrollBounds(y);
int height = getHeight();
int speed = 0;
if (y > mLowerBound) {
// scroll the list up a bit
speed = y > (height + mLowerBound) / 2 ? 16 : 4;
} else if (y < mUpperBound) {
// scroll the list down a bit
speed = y < mUpperBound / 2 ? -16 : -4;
}
if (speed != 0) {
int ref = pointToPosition(0, height / 2);
if (ref == AdapterView.INVALID_POSITION) {
//we hit a divider or an invisible view, check somewhere else
ref = pointToPosition(0, height / 2 + getDividerHeight() + 64);
}
View v = getChildAt(ref - getFirstVisiblePosition());
if (v != null) {
int pos = v.getTop();
setSelectionFromTop(ref, pos - speed);
}
}
}
public void setDropListener(DropListener l) {
mDropListener = l;
}
public interface DropListener {
void drop(int from, int to);
}
class Dragging {
private Context context;
private WindowManager windowManager;
private WindowManager.LayoutParams mWindowParams;
private ImageView mDragView;
private Bitmap mDragBitmap;
private int coordOffset;
private int mDragPoint; // at what offset inside the item did the user grab it
private int draggingItemHeight;
private int x;
private int y;
private int lastY;
public Dragging(Context context) {
this.context = context;
windowManager = (WindowManager) context.getSystemService("window");
}
/**
* #param y
* #param offset - the difference in y axis between screen coordinates and coordinates in this view
* #param view - which view is dragged
*/
public void start(int y, int offset, View view) {
this.y = y;
lastY = y;
this.coordOffset = offset;
mDragPoint = y - view.getTop();
draggingItemHeight = view.getHeight();
mDragView = new ImageView(context);
mDragView.setBackgroundResource(android.R.drawable.alert_light_frame);
// Create a copy of the drawing cache so that it does not get recycled
// by the framework when the list tries to clean up memory
view.setDrawingCacheEnabled(true);
mDragBitmap = Bitmap.createBitmap(view.getDrawingCache());
mDragView.setImageBitmap(mDragBitmap);
mWindowParams = new WindowManager.LayoutParams();
mWindowParams.gravity = Gravity.TOP;
mWindowParams.x = 0;
mWindowParams.y = y - mDragPoint + coordOffset;
mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
mWindowParams.format = PixelFormat.TRANSLUCENT;
mWindowParams.windowAnimations = 0;
windowManager.addView(mDragView, mWindowParams);
}
public void drag(int x, int y) {
lastY = this.y;
this.x = x;
this.y = y;
mWindowParams.y = y - mDragPoint + coordOffset;
windowManager.updateViewLayout(mDragView, mWindowParams);
}
public void stop() {
if (mDragView != null) {
windowManager.removeView(mDragView);
mDragView.setImageDrawable(null);
mDragView = null;
}
if (mDragBitmap != null) {
mDragBitmap.recycle();
mDragBitmap = null;
}
}
public int getDraggingItemHeight() {
return draggingItemHeight;
}
public int calculateHoverPosition() {
int adjustedY = (int) (y - mDragPoint + (Math.signum(y - lastY) + 2) * draggingItemHeight / 2);
// Log.v(LOG_TAG, "calculateHoverPosition(): lastY=" + lastY + ", y=" + y + ", adjustedY=" + adjustedY);
int pos = myPointToPosition(0, adjustedY);
if (pos >= 0) {
if (pos >= dragStartPosition) {
pos -= 1;
}
}
return pos;
}
}
}
I'm new with Android.
In my project I have the custom View MyView with the follow code
public class MyView extends View {
private final Bitmap baseBitmap = BitmapFactory.decodeResource(
getResources(), R.drawable.myImage);
private final Matrix matrix;
private boolean active = true;
public MyView(Context context, Matrix matrix) {
super(context);
this.matrix = matrix;
this.setFocusable(true);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (active) {
System.out.println("draw "+this.getId());
canvas.drawBitmap(baseBitmap, matrix, null);
} else {
...
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
System.out.println("--------->"+this.getId());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
this.matrix.setTranslate(event.getX()-(baseBitmap.getWidth()/2), event.getY()-(baseBitmap.getHeight()/2));
this.invalidate();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
this.active = false;
}
return true;
}
In my Activity, I instantiate MyView many times and then add them to the main layout. This is its code:
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();
float cx = display.getWidth() / 2, cy = display.getHeight() / 2;
int radius = 80;
double distance = 0, distancePoint = 0;
final int flags = PathMeasure.POSITION_MATRIX_FLAG
| PathMeasure.TANGENT_MATRIX_FLAG;
float length = 0;
setContentView(R.layout.main);
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_view);
Path pathCircle = new Path();
pathCircle.addCircle(cx, cy, radius, Direction.CW);
PathMeasure meas = new PathMeasure(pathCircle, false);
int nObject = 10;
length = meas.getLength();
distance = length/nObject;
int i = 0;
while(i<nObject){
Matrix m = new Matrix();
meas.getMatrix((float)distancePoint, m, flags);
MyView myView = new MyView(this, m);
System.out.println(myView.toString());
myView.setId(i);
mainLayout.addView(myView,i);
i++;
distancePoint = distance*i;
}
}
}
At runtime, when I touch any MyView element I always get the last. With "System.out.println("--------->"+this.getId());" I can see that the id of the touched element is always the last, even if I toch the first or any other element. Actualy, I just can move the last element.
Does anyone know why can't I get the event of the right istance of MyView touched?
(I hope my question is clear)
Thanks
I changed the code adding the onMeasure method. I used the code of a tutorial, dimensions are not specific for my image. The views are drawn and the result is the same, unfortunately with the same problem. I post the layout xml too, maybe could be useful.
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();
float cx = display.getWidth() / 2, cy = display.getHeight() / 2;
int radius = 80;
double distance = 0, distancePoint = 0;
final int flags = PathMeasure.POSITION_MATRIX_FLAG
| PathMeasure.TANGENT_MATRIX_FLAG;
float length = 0;
setContentView(R.layout.main);
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_view);
Path pathCircle = new Path();
pathCircle.addCircle(cx, cy, radius, Direction.CW);
PathMeasure meas = new PathMeasure(pathCircle, false);
int nObject = 10;
length = meas.getLength();
distance = length/nObject;
int i = 0;
while(i<nObject){
Matrix m = new Matrix();
meas.getMatrix((float)distancePoint, m, flags);
MyView myView = new MyView(this, m);
System.out.println(myView.toString());
myView.setId(i);
nt spec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
myView.measure(spec, spec);
mainLayout.addView(myView,i);
i++;
distancePoint = distance*i;
}
}
}
public class MyView extends View {
private final Bitmap baseBitmap = BitmapFactory.decodeResource(
getResources(), R.drawable.myImage);
private final Matrix matrix;
private boolean active = true;
public MyView(Context context, Matrix matrix) {
super(context);
this.matrix = matrix;
this.setFocusable(true);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (active) {
System.out.println("draw "+this.getId());
canvas.drawBitmap(baseBitmap, matrix, null);
} else {
...
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
System.out.println("--------->"+this.getId());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
this.matrix.setTranslate(event.getX()-(baseBitmap.getWidth()/2), event.getY()-(baseBitmap.getHeight()/2));
this.invalidate();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
this.active = false;
}
return true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int chosenWidth = chooseDimension(widthMode, widthSize);
int chosenHeight = chooseDimension(heightMode, heightSize);
int chosenDimension = Math.min(chosenWidth, chosenHeight);
setMeasuredDimension(chosenDimension, chosenDimension);
}
private int chooseDimension(int mode, int size) {
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else { // (mode == MeasureSpec.UNSPECIFIED)
return getPreferredSize();
}
}
// in case there is no size specified
private int getPreferredSize() {
return 300;
}
}
The main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/main_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF66FF33">
</RelativeLayout>
I'm pretty sure that it's because you're basically piling up your views at the top left corner of your RelativeLayout. So, only the uppermost (the last one added) is touchable.
I think that if you try adding them to a LinearLayout, as a test, you'll see that your view works. Setting LayoutParams for a RelativeLayout programmatically is not very comfy IMHO.
EDIT
I tried your code. The fact is that your views are just made to be drawn one over the other, or else the overall drawing wouldn't come, so my first guess is right (the uppermost covers the others - even in its transparent parts)(btw try Hierarchy Viewer and you can see that yourself). So you need to do your job in a single view, or handle the touches like this:
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if(!isPetaloTouched()) {// check if the actual drawing was touched
return false; // discard the event so that it reaches
// the underlying view
}
//......
See this post for an explanation of how events work in Android.
Both ways would need an isPetaloTouched() logic to detect if/which drawing must be moved, but the first would be more efficient of course.
Also, forget about the onMeasure() thing, I thought that could help giving the view a size around which to wrap, so that it wouldn't fill its parent and aligning views aside would make sense. However, be sure that the touch would work if the views were not piled up.
(...allora mPetali stava proprio per petali!)