(Xamarin with Visual Studio 2015 ) I want to implement a simple Activity inwith an Imageview, which can be moved/dragged with touch: This is what I have implemented, but the Image is flickering and moving slower. Can you give me an example how to implement this?
Thanks for your help!
private void TouchMeImageViewOnTouch(object sender, View.TouchEventArgs touchEventArgs)
{
View bild = (View)sender;
RelativeLayout.LayoutParams layouti = (RelativeLayout.LayoutParams)bild.LayoutParameters;
switch (touchEventArgs.Event.Action & MotionEventActions.Mask)
{
case MotionEventActions.Down:
xDelta = touchEventArgs.Event.GetX()-layouti.LeftMargin;
yDelta = touchEventArgs.Event.GetX() - layouti.LeftMargin;
break;
case MotionEventActions.Move:
int wert = (int)touchEventArgs.Event.GetX();
yvalue = touchEventArgs.Event.GetY()-yDelta;
xvalue = touchEventArgs.Event.GetX()-xDelta;
float xdpi = (int) Resources.DisplayMetrics.Density;
layouti.LeftMargin = (int)xvalue;
layouti.TopMargin = (int)yvalue;
container.Invalidate();
break;
case MotionEventActions.Up:
break;
default:
break;
}
xPositionText.Text = xvalue.ToString();
yPositionText.Text = yvalue.ToString();
}
I have tried to implement a dragable imageview for testing. the drag is slow in the android emulator. But by testing it in the real device it works fine and move fast.
Try the following code sample:
public class MainActivity : Activity, IOnTouchListener
{
Button dragAbleBt;
ImageView imgV1;
int screenWidth = 0;
int screenHeight = 0;
int lastX = 0, lastY = 0;
public bool OnTouch(View v, MotionEvent e)
{
MotionEventActions ea = e.Action;
switch (ea) {
case MotionEventActions.Down:
lastX = (int)e.RawX;
lastY = (int)e.RawY;
break;
case MotionEventActions.Move:
int dx = (int)e.RawX - lastX;
int dy = (int)e.RawY - lastY;
int left = v.Left + dx;
int right = v.Right + dx;
int top = v.Top + dy;
int bottom = v.Bottom + dy;
if (left < 0)
{
left = 0;
right = left + v.Width;
}
if (right > screenWidth)
{
right = screenWidth;
left = right - v.Width;
}
if (top < 0)
{
top = 0;
bottom = top + v.Height;
}
if (bottom > screenHeight)
{
bottom = screenHeight;
top = bottom - v.Height;
}
v.Layout(left, top, right, bottom);
lastX = (int) e.RawX;
lastY = (int) e.RawY;
v.PostInvalidate();
break;
case MotionEventActions.Up:
break;
}
if (v.Id == Resource.Id.imageView1)
{
return true;
}
return false;
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView (Resource.Layout.Main);
//DisplayMetrics dm = Resources.DisplayMetrics;
//screenWidth = dm.WidthPixels;
//screenHeight = dm.HeightPixels;
dragAbleBt = FindViewById<Button>(Resource.Id.button1);
imgV1 = FindViewById<ImageView>(Resource.Id.imageView1);
dragAbleBt.SetOnTouchListener(this);
imgV1.SetOnTouchListener(this);
}
public override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
if (hasFocus)
{
Rect outRect = new Rect();
this.Window.FindViewById(Window.IdAndroidContent).GetDrawingRect(outRect);
screenWidth = outRect.Width();
screenHeight = outRect.Height();
}
}
}
Please refer the source code to the github
Related
I have two activities; one is IntermediateActivity, and one is the DragAndDrop activity. The IntermediateActivity has a 5-second timer, and a visitcount variable incremented every time the IntermediateActivity is opened. After the timer is over, the DragAndDrop activity is opened, in which the user has to drag a circle to the desired position, and when the user can do that, I start an intent that opens the the IntermediateActivity again.
What is happening is that for the runs of DragAndDrop when the IntermediateActivity is opened, the visit count gets incremented by 2 instead of one.
Here's how I call the intent for IntermediateActivity in the DragAndDrop Activity :
public class DragAndDrop extends AppCompatActivity implements View.OnTouchListener{
private ImageView img;
private ImageView img_outline;
private ViewGroup rootLayout;
private int _xDelta;
private int _yDelta;
#SuppressLint("ClickableViewAccessibility")
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
List<Integer> givenList = Arrays.asList(0, 1, 2, 3);
Random rand = new Random();
int randomElement = givenList.get(rand.nextInt(givenList.size()));
// Randomise location of Circle
switch (randomElement){
case 0:
setContentView(R.layout.bottom_left);
rootLayout = (ViewGroup) findViewById(R.id.bottom_left_layout);
img = (ImageView) rootLayout.findViewById(R.id.circle_bottomLeft);
img_outline = findViewById(R.id.circle_outline_bottomLeft);
break;
case 1:
setContentView(R.layout.bottom_right);
rootLayout = (ViewGroup) findViewById(R.id.bottom_right_layout);
img = (ImageView) rootLayout.findViewById(R.id.circle_bottomRight);
img_outline = findViewById(R.id.circle_outline_bottomRight);
break;
case 2:
setContentView(R.layout.top_left);
rootLayout = (ViewGroup) findViewById(R.id.top_left_layout);
img = (ImageView) rootLayout.findViewById(R.id.circle_topleft);
img_outline = findViewById(R.id.circle_outline_topleft);
break;
case 3:
setContentView(R.layout.top_right);
rootLayout = (ViewGroup) findViewById(R.id.top_right_layout);
img = (ImageView) rootLayout.findViewById(R.id.circle_topRight);
img_outline = findViewById(R.id.circle_outline_topRight);
break;
}
img.setOnTouchListener(this);
}
public void check_success(){
float centreX = img.getX() + img.getWidth() / 2;
float centreY = img.getY() + img.getHeight() / 2;
float centreX_outline = img_outline.getX() + img_outline.getWidth() / 2;
float centreY_outline = img_outline.getY() + img_outline.getHeight() / 2;
// Location Range for 150 x 150dp square with center = center of outline
if((centreX >= centreX_outline-75) &&(centreX <= centreX_outline+75)
&& (centreY >= centreY_outline-75) &&(centreY <= centreY_outline+75)){
// Vibrate
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
v.vibrate(500);
}
// Start Intermediate Activity
Intent i = new Intent(DragAndDrop.this, IntermediateActivity.class);
startActivity(i);
}
}
public boolean onTouch(View view, MotionEvent event) {
check_success();
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.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:
//Drag Functionality
ViewGroup.MarginLayoutParams marginParams = new ViewGroup.MarginLayoutParams(img.getLayoutParams());
int left = (int) event.getRawX() - (view.getWidth() / 2);
int top = (int) event.getRawY() - (view.getHeight());
marginParams.setMargins(left, top, 0, 0);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
img.setLayoutParams(layoutParams);
break;
}
rootLayout.invalidate();
return true;
}
}
And here's the code for the IntermediateActivity in which the variablevisitCount tracks the number of times the activity is called :
private TextView footer_text;
private TextView timer_text;
public int timer_counter;
static int visitCount = 0;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.intermediate_screen);
timer_text = findViewById(R.id.timer);
footer_text = findViewById(R.id.footer);
timer_counter = 5;
Resources resource = getResources();
if (resource.getConfiguration().locale.getLanguage() == "hi") {
footer_text.setText("कार्य की पूर्णता : " + String.valueOf(visitCount) + "/30");
} else {
footer_text.setText("Tasks completed: " + String.valueOf(visitCount) + "/30");
}
visitCount++;
if (visitCount == 31) {
visitCount = 0;
Intent k = new Intent(IntermediateActivity.this, MainActivity.class);
startActivity(k);
} else {
new CountDownTimer(5000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timer_text.setText(String.valueOf(timer_counter));
timer_counter--;
}
#Override
public void onFinish() {
i = new Intent(IntermediateActivity.this, DragAndDrop.class);
startActivity(i);
}
}.start();
}
}
I tried to go through the code multiple times but I couldn't get why the count would be getting incremented multiple times even when the intent would be sent only once.
I have been trying to make a gridview with drag and drop functionality along with one cell of different size. I have already made the the grid drag and drop and its working fine. you can check the code from here
but I want it to be like this and purely dynamic as I will be draging and dropping the other which will be replaced and resized automatically
Updated with new code that accommodates resizing of cells.
Your question refers to GridView but the code you supplied doesn't mention GridView but uses GridLayout instead, so I am assuming that GridLayout is the right layout.
I have put together a demo using a mocked-up layout with one 2x2 tile. I have modified the code that you have supplied to accommodate the 2x2 tile. Other than the code that I added to implement the 2x2 tile, the only other change to MainAcitivity was to the calculateNextIndex method that uses a different way of calculating the index at an (x, y) position. Layouts and the LongPressListener class were also mocked up since they were not supplied.
Here is a video of the demo:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final int ITEMS = 10;
private GridLayout mGrid;
private ScrollView mScrollView;
private ValueAnimator mAnimator;
private Boolean isScroll = false;
private GridLayout.Spec m1xSpec = GridLayout.spec(GridLayout.UNDEFINED, 1);
private GridLayout.Spec m2xSpec = GridLayout.spec(GridLayout.UNDEFINED, 2);
private int mBaseWidth;
private int mBaseHeight;
private int mBaseMargin;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mScrollView = (ScrollView) findViewById(R.id.scrollView);
mScrollView.setSmoothScrollingEnabled(true);
mGrid = (GridLayout) findViewById(R.id.grid);
mGrid.setOnDragListener(new DragListener());
final LayoutInflater inflater = LayoutInflater.from(this);
GridLayout.LayoutParams lp;
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
float dpiToPx = displayMetrics.density;
View view = inflater.inflate(R.layout.item, mGrid, false);
lp = (GridLayout.LayoutParams) view.getLayoutParams();
mBaseWidth = lp.width;
mBaseHeight = lp.height;
mBaseMargin = lp.rightMargin;
for (int i = 0; i < ITEMS; i++) {
final View itemView = inflater.inflate(R.layout.item, mGrid, false);
final TextView text = (TextView) itemView.findViewById(R.id.text);
text.setText(String.valueOf(i + 1));
itemView.setOnLongClickListener(new LongPressListener());
lp = (i == 0) ? make2x2LayoutParams(itemView) : make1x1LayoutParams(itemView);
mGrid.addView(itemView, lp);
}
}
private GridLayout.LayoutParams make2x2LayoutParams(View view) {
GridLayout.LayoutParams lp = (GridLayout.LayoutParams) view.getLayoutParams();
lp.width = mBaseWidth * 2 + 2 * mBaseMargin;
lp.height = mBaseHeight * 2 + 2 * mBaseMargin;
lp.rowSpec = m2xSpec;
lp.columnSpec = m2xSpec;
lp.setMargins(mBaseMargin, mBaseMargin, mBaseMargin, mBaseMargin);
return lp;
}
private GridLayout.LayoutParams make1x1LayoutParams(View view) {
GridLayout.LayoutParams lp = (GridLayout.LayoutParams) view.getLayoutParams();
lp.width = mBaseWidth;
lp.height = mBaseHeight;
lp.setMargins(mBaseMargin, mBaseMargin, mBaseMargin, mBaseMargin);
lp.rowSpec = m1xSpec;
lp.columnSpec = m1xSpec;
return lp;
}
private int mDraggedIndex;
class DragListener implements View.OnDragListener {
#Override
public boolean onDrag(View v, DragEvent event) {
final View view = (View) event.getLocalState();
int index = calculateNextIndex(event.getX(), event.getY());
View child;
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
mDraggedIndex = index;
break;
case DragEvent.ACTION_DRAG_LOCATION:
if (view == v) return true;
// get the new list index
final Rect rect = new Rect();
mScrollView.getHitRect(rect);
final int scrollY = mScrollView.getScrollY();
if (event.getY() - scrollY > mScrollView.getBottom() - 250) {
startScrolling(scrollY, mGrid.getHeight());
} else if (event.getY() - scrollY < mScrollView.getTop() + 250) {
startScrolling(scrollY, 0);
} else {
stopScrolling();
}
child = mGrid.getChildAt(0);
if (index == 0) {
child.setLayoutParams(make1x1LayoutParams(child));
view.setLayoutParams(make2x2LayoutParams(view));
} else if (mDraggedIndex == 0) {
view.setLayoutParams(make1x1LayoutParams(view));
child.setLayoutParams(make2x2LayoutParams(child));
} else {
child.setLayoutParams(make2x2LayoutParams(child));
view.setLayoutParams(make1x1LayoutParams(view));
}
mGrid.removeView(view);
mGrid.addView(view, index);
break;
case DragEvent.ACTION_DROP:
for (int i = 0; i < mGrid.getChildCount(); i++) {
child = mGrid.getChildAt(i);
child.setLayoutParams(make1x1LayoutParams(child));
}
mGrid.removeView(view);
if (index == 0) {
view.setLayoutParams(make2x2LayoutParams(view));
}
mGrid.addView(view, index);
view.setVisibility(View.VISIBLE);
mGrid.getChildAt(0).setLayoutParams(make2x2LayoutParams(mGrid.getChildAt(0)));
break;
case DragEvent.ACTION_DRAG_ENDED:
if (!event.getResult()) {
view.setVisibility(View.VISIBLE);
}
break;
}
return true;
}
}
private void startScrolling(int from, int to) {
if (from != to && mAnimator == null) {
isScroll = true;
mAnimator = new ValueAnimator();
mAnimator.setInterpolator(new OvershootInterpolator());
mAnimator.setDuration(Math.abs(to - from));
mAnimator.setIntValues(from, to);
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mScrollView.smoothScrollTo(0, (int) valueAnimator.getAnimatedValue());
}
});
mAnimator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
isScroll = false;
mAnimator = null;
}
});
mAnimator.start();
}
}
private void stopScrolling() {
if (mAnimator != null) {
mAnimator.cancel();
}
}
private int calculateNextIndexOld(float x, float y) {
// calculate which column to move to
final float cellWidth = mGrid.getWidth() / mGrid.getColumnCount();
final int column = (int) (x / cellWidth);
final float cellHeight = mGrid.getHeight() / mGrid.getRowCount();
final int row = (int) Math.floor(y / cellHeight);
int index = row * mGrid.getColumnCount() + column;
if (index >= mGrid.getChildCount()) {
index = mGrid.getChildCount() - 1;
}
Log.d("MainActivity", "<<<<index=" + index);
return index;
}
private int calculateNextIndex(float x, float y) {
// calculate which column to move to
int index;
for (index = 0; index < mGrid.getChildCount(); index++) {
View child = mGrid.getChildAt(index);
Rect rect = new Rect();
child.getHitRect(rect);
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
break;
}
}
if (index >= mGrid.getChildCount()) {
// Move into empty cell? Calculate based upon uniform cell sizes.
index = calculateNextIndexOld(x, y);
}
if (index >= mGrid.getChildCount()) {
// Can't determine where to put it? Add it to the end.
index = mGrid.getChildCount() - 1;
}
return index;
}
}
If you work with the demo a little, you will see that it is possible to move tiles such that a 1x1 tile gap is opened up. This may be OK, but the code may need to be reworked a little if not.
You can try :
https://github.com/askerov/DynamicGrid
I hope it can help your problem!
I am creating a floor map with n number of dynamic buttons with incremental value and added to a custom relative layout. Now i need to create onclicklistner for each buttons added to a view. How to get the id or some unique value to identify which button is clicked. Can somebody please help me on this i am breaking my head for the past 10 days. Thanks in advance.
This is my Custom Relative layout :
public class InteractiveView extends RelativeLayout implements OnClickListener{
Matrix matrix = new Matrix();
private float mPositionX = 0;
private float mPositionY = 0;
private float mScale = 0.1f;
private Context context;
private boolean canvasFlag = true;
public InteractiveView(Context context) {
super(context);
this.context = context;
this.setWillNotDraw(false);
// this.setOnTouchListener(mTouchListener);
this.setOnClickListener(this);
}
public void setPosition(float lPositionX, float lPositionY){
mPositionX = lPositionX;
mPositionY = lPositionY;
}
public void setMovingPosition(float lPositionX, float lPositionY){
mPositionX += lPositionX;
mPositionY += lPositionY;
}
public void setScale(float lScale){
mScale = lScale;
}
protected void dispatchDraw(Canvas canvas) {
canvas.save();
// canvas.setMatrix(matrix);
Log.e("Canvas Height ",canvas.getWidth()+" "+canvas.getHeight());
Log.e("Canvas Height ",getWidth() /14 +" "+getHeight()/12 );
Log.e("Canvas Density "," "+canvas.getDensity() );
canvas.translate(mPositionX*mScale, mPositionY*mScale);
canvas.translate(getWidth() / 14,getHeight() / 12);
if (mScale < 0.10)
mScale = 0.1f;
canvas.scale(mScale, mScale);
Log.e("Scale : ",mScale+" ");
super.dispatchDraw(canvas);
canvas.restore();
}
// touch events
private final int NONE = 0;
private final int DRAG = 1;
private final int ZOOM = 2;
private final int CLICK = 3;
// pinch to zoom
private float mOldDist;
private float mNewDist;
private float mScaleFactor = 0.01f;
// position
private float mPreviousX;
private float mPreviousY;
int mode = NONE;
#SuppressWarnings("deprecation")
public OnTouchListener mTouchListener = new OnTouchListener(){
public boolean onTouch(View v, MotionEvent e) {
/*Button button = (Button)v;
Log.e("Button Text : "," "+button.getText().toString());
*/
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN: // one touch: drag
mode = CLICK;
break;
case MotionEvent.ACTION_POINTER_2_DOWN: // two touches: zoom
mOldDist = spacing(e);
mode = ZOOM; // zoom
break;
case MotionEvent.ACTION_UP: // no mode
mode = NONE;
break;
case MotionEvent.ACTION_POINTER_2_UP: // no mode
mode = NONE;
break;
case MotionEvent.ACTION_MOVE: // rotation
if (e.getPointerCount() > 1 && mode == ZOOM) {
/*mNewDist = spacing(e) - mOldDist;
mScale += mNewDist*mScaleFactor;
invalidate();
mOldDist = spacing(e); */
} else if (mode == CLICK || mode == DRAG) {
float dx = (x - mPreviousX)/mScale;
float dy = (y - mPreviousY)/mScale;
setMovingPosition(dx, dy);
invalidate();
mode = DRAG;
}
break;
}
mPreviousX = x;
mPreviousY = y;
return true;
}
};
// finds spacing
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y)/4;
}
This is my fragment class where i create floor map :
public class FloorMapFragment extends Fragment implements OnClickListener {
ViewGroup root;
Button exhibitor;
ZoomControls zoom;
int id = 0;
float dx=0,dy=0,x=0,y=0;
InteractiveView mInteractiveView;
int startX, startY;
boolean isClicked = false;
int unit = 100;
int incremental = 100;
int new_X;
int i;
int new_Width = new_X + incremental;
int new_Y;
int new_Hight = new_Y + incremental;
int leftMargin, topMargin;
int orange = Color.parseColor("#C0680F");
int maroon = Color.parseColor("#5F0C0C");
int pink = Color.parseColor("#F45C91");
int moov = Color.parseColor("#6E4689");
int gray = Color.parseColor("#777777");
int red = Color.parseColor("#E31E26");
int blue = Color.parseColor("#3A53A4");
int green = Color.parseColor("#70BD59");
int cyan = Color.parseColor("#70CDDD");
RelativeLayout r;
// View mainView = null;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
PointF oldDistPoint = new PointF();
public static String TAG = "ZOOM";
int mScreenWidth = 0;
int mScreenHeight= 0;
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
enum Direction {
LEFT, RIGHT, UP, DOWN
};
FloorListner listner;
#SuppressWarnings("deprecation")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
root = (ViewGroup) inflater.inflate(R.layout.floor_main, null);
// mainView = (RelativeLayout)root.findViewById(R.id.zoom_layout);
r = (RelativeLayout) root.findViewById(R.id.my_relative_layout);
zoom = (ZoomControls)root. findViewById(R.id.zoomControls1);
mScreenWidth = r.getWidth();
/*MainActivity.activity.getResources()
.getDisplayMetrics().widthPixels;*/
mScreenHeight = r.getHeight();
/*MainActivity.activity.getResources()
.getDisplayMetrics().heightPixels; */
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT);
layoutParams.height = 75;
layoutParams.width = 57;
// layoutParams.bottomMargin = 100;
// layoutParams.setMargins(0, 0, 0, 100);
// layoutParams.setMargins(-220, 0, 0, 0);
/*ImageView lImageView = new ImageView(MainActivity.activity);
lImageView.setLayoutParams(new RelativeLayout.LayoutParams(-1,-1));
lImageView.setImageResource(R.drawable.transparentimage);;*/
mInteractiveView = new InteractiveView(MainActivity.activity);
// mInteractiveView.setOnClickListener(this);
// mInteractiveView.setOnTouchListener(mTouchListener);
// mInteractiveView.setLayoutParams(new RelativeLayout.LayoutParams(-5,-5 ));
// mInteractiveView.setLayoutParams(layoutParams);
// mInteractiveView.setPosition(-mScreenWidth/2, -mScreenHeight/2);
zoom.setOnZoomInClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
float x = r.getScaleX();
float y = r.getScaleY();
Log.e("Zoon In Listener : ", "X Scale : "+ x );
Log.e("Zoon In Listener : ", "Y Scale : "+ y );
Log.e("Zoon In Width : ", "X Scale : "+ r.getWidth() );
Log.e("Zoon In Height : ", "Y Scale : "+ r.getHeight() );
if (x <= 6.0 && y <= 6.0){
r.setScaleX((float) (x + 0.5));
r.setScaleY((float) (y + 0.5));
}
}
});
zoom.setOnZoomOutClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
float x = r.getScaleX();
float y = r.getScaleY();
Log.e("Zoon Out Listener : ", "X Scale : "+ x );
Log.e("Zoon Out Listener : ", "Y Scale : "+ y );
if (x > 1.0 && y > 1.0){
r.setScaleX((float) (x - 0.5));
r.setScaleY((float) (y - 0.5));
}
}
});
ProgressDialog d = new ProgressDialog(getActivity());
d.setMessage("Loading Map");
d.show();
draw();
d.dismiss();
/*
mInteractiveView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});*/
/*for( i=0; i<((ViewGroup)mInteractiveView).getChildCount(); ++i) {
View nextChild = ((ViewGroup)mInteractiveView).getChildAt(i);
try {
final Button b = (Button) nextChild;
Log.e("Button Text : ", " : "+b.getText().toString());
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int index = ((ViewGroup)b.getParent()).indexOfChild(b);
Log.e("Button get Id : ", ""+v.getTag().toString());
}
});
} catch (Exception e) {
}
}*/
//
// mInteractiveView.addView(lImageView);
// r.setLayoutParams(layoutParams);
r.addView(mInteractiveView);
/* ExhibitorDAO dao = new ExhibitorDAO(getActivity());
workAround(dao, "K19");*/
/* Fragment fragment = new NewsFragment();
FragmentTransaction trans = ;
trans.addToBackStack(null);
trans.replace(R.id.main, fragment);
trans.commit();*/
// r.setOnTouchListener(MyOnTouchListener);
// r.setLayoutParams(layoutParams);
Log.e("Width And Height : ", "Width : "+r.getLayoutParams().width+ " : Height :"+r.getLayoutParams().height);
return root;
}
private OnTouchListener mTouchListener = new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
isClicked = true;
x = event.getX();
y = event.getY();
dx = x-r.getX();
dy = y-r.getY();
break;
case MotionEvent.ACTION_UP:
if (isClicked){
isClicked = false;
/*Button b = (Button) v;
ExhibitorDAO dao = new ExhibitorDAO(getActivity());
workAround(dao,b.getText().toString());*/
}
break;
case MotionEvent.ACTION_POINTER_UP:
isClicked = false;
break;
case MotionEvent.ACTION_POINTER_DOWN:
isClicked = false;
break;
case MotionEvent.ACTION_MOVE:
r.setX(event.getX()-dx);
r.setY(event.getY()-dy);
isClicked = false;
break;
default:
break;
}
return false;
}
};
private void decreaseXBy(int i) {
new_X = new_X - (2 * i);
}
private void reset() {
new_X = 0;
new_Y += incremental;
;
}
private void drawingH(Direction direction, float width) {
if (direction == direction.RIGHT) {// means go to right direction{
new_X += (incremental * width);
} else if (direction == direction.LEFT) { // means go to left
new_X -= (incremental * width);
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Button b = (Button) v;
ExhibitorDAO dao = new ExhibitorDAO(getActivity());
try{
Exhibitor exhibitor = new Exhibitor();
Log.e("Button Text : ", " : "+b.getText());
if (!b.getText().equals("")) {
Logger.log("floor:");
exhibitor = dao.getExhibitorByBooth(b.getText().toString());
ExhibitorApplication ex = new ExhibitorApplication();
ex.exhibitor = exhibitor;
if (exhibitor != null){
listner.Onfloorclick();
ex.fav_exhibitor = 4 ;
Logger.log("floor:"+ex.exhibitor.Exhibitor_FileNumber);
}
else
{
Logger.log("floor:"+ex.exhibitor.Exhibitor_FileNumber);
}
}
{
Logger.log("floor:no data");
}
}
catch(Exception ex)
{
Toast.makeText(getActivity(), "No Information "+ex.getMessage(), Toast.LENGTH_SHORT).show();
}
}
public Button drawExhibitor(float width, int height, int color,
String label, String fileNumber, Direction d) {
exhibitor = new Button(getActivity());
// exhibitor.setOnClickListener(this);
// exhibitor.setOnTouchListener(MyOnTouchListener);
if (color == Color.BLUE)
exhibitor.setBackgroundColor(Color.parseColor("#56A5EC"));
if (color == Color.WHITE)
exhibitor.setAlpha(0);
else
exhibitor.setBackgroundColor(color);
// exhibitor.setId(id);
// id++;
exhibitor.setText(label);
exhibitor.setTextSize(8);
// exhibitor.setId(foo);
exhibitor.setTag(label);
exhibitor.setTypeface(Typeface.DEFAULT_BOLD);
exhibitor.setGravity(Gravity.CENTER);
exhibitor.setTextColor(Color.WHITE);
/*exhibitor.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("Button get Id : ", ""+exhibitor.getId());
}
});*/
exhibitor.setOnTouchListener(mTouchListener);
leftMargin = new_X;
topMargin = new_Y;
drawingH(d, width);
InteractiveView.LayoutParams params = new InteractiveView.LayoutParams(
(int) (width * incremental), height * incremental);
params.leftMargin = leftMargin;
params.topMargin = topMargin;
mInteractiveView.addView(exhibitor, params);
params = null;
if (color != Color.WHITE) {
drawingHSpace();
}
return exhibitor;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof FloorListner) {
listner = (FloorListner) activity;
} else {
throw new ClassCastException(activity.toString()
+ " must implemenet MyListFragment.OnItemSelectedListener");
}
}
private void drawingHSpace() {
new_X += 2;
}
private void drawingHSpace(float t) {
new_X = (int) (new_X + (2 * t));
}
private void drawingVSpace() {
new_Y += 2;
}
private void removeDrawingVSpace() {
new_Y -= 2;
}
private void decreaseXBy(float i) {
new_X = (int) (new_X - (2 * i));
}
private void drawLabel(float width, int height, int color, int drawable, Direction d) {
// TODO Auto-generated method stub
TextView image = new TextView(getActivity());
//image.setText(label);
image.setBackgroundResource(drawable);
image.setGravity(Gravity.CENTER);
image.setTextSize(20);
image.setTypeface(Typeface.DEFAULT_BOLD);
//image.setTextColor(color);
// image.setOnTouchListener(MyOnTouchListener);
leftMargin = new_X;
topMargin = new_Y;
drawingH(d,width);
InteractiveView.LayoutParams params = new InteractiveView.LayoutParams(
(int)(width * incremental), height * incremental);
params.leftMargin = leftMargin;
params.topMargin = topMargin;
mInteractiveView.addView(image, params);
}
private void drawLabel(float width, int height, int color, String label, Direction d) {
// TODO Auto-generated method stub
TextView image = new TextView(getActivity());
image.setText(label);
image.setGravity(Gravity.CENTER);
image.setTextSize(20);
image.setTypeface(Typeface.DEFAULT_BOLD);
image.setTextColor(color);
// image.setOnTouchListener(mTouchListener);
leftMargin = new_X;
topMargin = new_Y;
drawingH(d,width);
InteractiveView.LayoutParams params = new InteractiveView.LayoutParams(
(int)(width * incremental), height * incremental);
params.leftMargin = leftMargin;
params.topMargin = topMargin;
mInteractiveView.addView(image, params);
}
private void draw() {
drawExhibitor(28.5F, 3, Color.WHITE, "", "", Direction.RIGHT);
drawLabel(2, 3, blue, R.drawable.al_mamzar, Direction.RIGHT);
reset();
reset();
drawExhibitor(16.5F, 1, Color.WHITE, "", "", Direction.RIGHT);
drawLabel(2, 1, blue, R.drawable.business_center, Direction.RIGHT);
drawExhibitor(4.65F, 1, Color.WHITE, "", "", Direction.RIGHT);
drawLabel(1, 1, blue, R.drawable.bath_f, Direction.RIGHT);
drawExhibitor(14F, 1, Color.WHITE, "", "", Direction.RIGHT);
drawLabel(1, 1, blue, R.drawable.bath_m, Direction.RIGHT);
//reset();
reset();
drawingVSpace();
drawingVSpace();
}
}
Finally i am adding the Interactive View to a relative layout.
As you will find it in the documentation that each view can have an id (using setId (int id) or from xml android:id ) or tag(using setTag (int key)) associated with it and later on you can get that id or tag via getId() or getTag().
Now before you actually retrieve any id for a view at first you have to set an id for that specific view either via programmatically or via xml.
If you don't specify any id for a view and you are trying get that view's id you will get NO_ID.
As per documentation: getId () returns this view's identifier.A positive integer used to identify the view or NO_ID if the view has no ID.
Now to address your problem, before you add a button to your viewgroup assign a unique id to that button.
To illustrate more here is an example:
public class MainActivity extends Activity {
private LinearLayout mRootLayout;
private OnClickListener mOnClickListener = new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Log.e("mButton "," onClick");
Toast.makeText(MainActivity.this, " "+arg0.getId(), Toast.LENGTH_LONG).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRootLayout = (LinearLayout)findViewById(R.id.mRootLayout);
for(int i = 0;i<10;i++){
Button mButton = new Button(this);
mButton.setText("Button "+i);
mButton.setId(i);
if(i<9){
mButton.setOnClickListener(mOnClickListener);
}
mRootLayout.addView(mButton);
}
Button testFindButton = (Button)mRootLayout.findViewById(9);
testFindButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.e("testFindButton "," onClick");
Toast.makeText(MainActivity.this, " testFindButton "+v.getId(), Toast.LENGTH_LONG).show();
}
});
}
}
You can use the setTag method for each button, to set an id. Then in the onClick method, retrieve that value, and execute the code related to that button.
Some code (not tested):
private OnClickListener listener = new OnClickListener()
{
#Override
public void onClick(View v)
{
int id = (Integer)v.getTag();
switch (id)
{
case 1: break;
....
}
}
});
for (int i=0 ; i<N ; i++)
{
yourbutton.setTag(Integer.valueOf(i));
yourbutton.setOnClickListener(listener);
}
I want to drag a view. Until now i tried it with a LinearLayout and margins and with a AbsoluteLayout.
AbsoluteLayout example:
button.Touch = (clickedView, motionEvent) =>
{
Button b = (Button)clickedView;
if (motionEvent.Action == MotionEventActions.Move)
{
AbsoluteLayout.LayoutParams layoutParams = new AbsoluteLayout.LayoutParams(100, 35, (int)motionEvent.GetX(), (int)motionEvent.GetY());
b.LayoutParameters = layoutParams;
}
return true;
};
In every case I tried I got a curios behaviour. Here's why. The view i'm dragging follows my finger but jumps always between two positions. One postition hits my finger the other is somewhere to my fingers left-top. If I'm just writing my current position into a textview (without moving the view) the coordinates behave as expected. But if i'm also moving the view they are jumping again.
How can i avoid this?
EDIT: I used sounds comment on my question to implement a working draging for monodroid (it is done for Java/Android SDK in the linked site). Maybe others are interested in doing that some day, so here's my solution:
[Activity(Label = "Draging", MainLauncher = true, Icon = "#drawable/icon")]
public class Activity1 : Activity
{
private View selectedItem = null;
private int offset_x = 0;
private int offset_y = 0;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
ViewGroup vg = (ViewGroup)FindViewById(Resource.Id.vg);
vg.Touch = (element, motionEvent) =>
{
switch (motionEvent.Action)
{
case MotionEventActions.Move:
int x = (int)motionEvent.GetX() - offset_x;
int y = (int)motionEvent.GetY() - offset_y;
int w = WindowManager.DefaultDisplay.Width - 100;
int h = WindowManager.DefaultDisplay.Height - 100;
if (x > w)
x = w;
if (y > h)
y = h;
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
new ViewGroup.MarginLayoutParams(
LinearLayout.LayoutParams.WrapContent,
LinearLayout.LayoutParams.WrapContent));
lp.SetMargins(x, y, 0, 0);
selectedItem.LayoutParameters = lp;
break;
default:
break;
}
return true;
};
ImageView img = FindViewById<ImageView>(Resource.Id.img);
img.Touch = (element, motionEvent) =>
{
switch (motionEvent.Action)
{
case MotionEventActions.Down:
offset_x = (int)motionEvent.GetX();
offset_y = (int)motionEvent.GetY();
selectedItem = element;
break;
default:
break;
}
return false;
};
}
}
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;
}
}
}