dear. I want to scroll my floating window, but it's not scrolling and the pinch-to-zoom feature isn't working. Can you please help me fix this issue?"
MotionEvent.ACTION_MOVE -> {
if (event.pointerCount == 1 && !touchConsumedByMove) {
//Add logic for minimizing/maximizing the window
if (Math.abs(event.rawY.toInt() - firstY) > 100) {
if (isMinimized) {
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
Related
Right now I've been developing a game which will make the character move up or down if either swipe up or down on the left side of the screen. Then, he can also, shoot projectiles if I tap the right side of the screen. I've succeeded on making it work but the problem is that the swipe function do not works while I tap the the right screen. Both only works if I do one of them. I cannot move the character if I am firing projectiles. Any suggestions? Appreciate it in advanced.
Here's the code:
For the swipe movement function:
void Swipe() {
if (Input.touchCount > 0) {
Touch t = Input.GetTouch(0);
if (t.phase == TouchPhase.Began)
{
lp = t.position;
fp = t.position;
text.text = fp.x.ToString();
}
else if (t.phase == TouchPhase.Ended)
{
lp = t.position;
//Swipe Up
if (fp.y < lp.y && fp.x < 400)
{
currentLane += 1;
}
//Swipe Down
else if (fp.y > lp.y && fp.x < 400)
{
currentLane -= 1;
}
}
}
}
And here's the code for the tap or firing projectiles function:
void FireBullets() {
interval += 2 * Time.deltaTime;
anim.SetBool("Attacking", firing);
if (Input.touchCount > 0 && interval > .75f) {
Vector3 bulletTouchPos;
Touch bulletT = Input.GetTouch(0);
bulletTouchPos = bulletT.position;
if (bulletT.phase == TouchPhase.Began) {
if (bulletTouchPos.x > 400)
{
interval = 0;
firing = true;
//Fire Bullets
Instantiate(bullets, new Vector3(transform.position.x + 1.2f, transform.position.y + .3f, transform.position.z), Quaternion.identity);
}
}
}else
{
firing = false;
}
}
Your lp and fp values don't care which finger is being checked.
If you want to detect multiple touch gestures at once, you need to discriminate your detection based on which finger that is.
You can do this by looking at the Touch.fingerId value, which is unique for each finger. Fingers are just an ID assigned to a given touching point as it moves across the screen in order to identify it from other touching points currently also on the screen.
You'll need to adjust your code to handle how to store the information you need in order to do what you need, but this should get you started.
Here is a picture of what I'm trying to do:
So, I want to resize a single cell while dragging resize anchors (black quads) which are ImageViews. To do this I attached custom onTouchListener to them that does next in MotionEvent.ACTION_MOVE:
calculate drag offset
set cell height/width based on this offset
reposition anchor point by changing it's layout params
The outcome of this is that the cell resizes but there is some king of flicker, more like shaking left/right or up/down, by some small offset.
My guess is that the problem comes when it catches move event, then I manualy change position of anchor and then, when it catches move event again it doesn't handle that change well...or something
I have an idea to put invisible ImageViews under each anchor and do resize based on their movement but do not move that anchor while draging. Then when I relese it, it lines up with coresponding visible anchor. But this is more hacking than solution :)
And finally, does anubody know why is this happening?
EDIT:
Here is the code where I'm handlign move event:
float dragY = event.getRawY() - resizePreviousPositionY;
LinearLayout.LayoutParams componentParams = (LinearLayout.LayoutParams)selectedComponent.layout.getLayoutParams();
LinearLayout parrent = (LinearLayout)selectedComponent.layout.getParent();
View topSibling = parrent.getChildAt(parrent.indexOfChild(selectedComponent.layout) - 1);
LinearLayout.LayoutParams topSiblingParams = (LinearLayout.LayoutParams)topSibling.getLayoutParams();
if(dragY > 0 && selectedComponent.layout.getHeight() > 100 ||
dragY < 0 && topSibling.getHeight() > 100)
{
componentParams.height = selectedComponent.layout.getHeight() - (int)dragY;
topSiblingParams.height = topSibling.getHeight() + (int)dragY;
//bottomSiblingParams.height = bottomSibling.getHeight();
selectedComponent.layout.setLayoutParams(componentParams);
repositionResizeAnchors(selectedComponent);
}
resizePreviousPositionY = event.getRawY();
and here is where I reposition it:
if(((LinearLayout)viewHolder.layout.getParent()).getOrientation() == LinearLayout.VERTICAL)
{
leftMargin = ((LinearLayout)viewHolder.layout.getParent()).getLeft() +
viewHolder.layout.getLeft() + viewHolder.layout.getWidth()/2;
}
else
{
leftMargin = viewHolder.layout.getLeft() + viewHolder.layout.getWidth()/2;
}
topMargin = viewHolder.layout.getTop();
params = (RelativeLayout.LayoutParams)resizeTop.getLayoutParams();
params.leftMargin = leftMargin - dpToPx(resizeAnchorRadius/2);
params.topMargin = topMargin - dpToPx(resizeAnchorRadius/2);
resizeTop.setLayoutParams(params);
I would like to rotate my gameobject without using the z-axis, so that it only rotates horizontal and vertical.
Right now I am using this code
void Update () {
if (Input.touchCount == 1) {
var touch = Input.GetTouch(0);
switch(Input.GetTouch(0).phase){
case TouchPhase.Moved:
float swipeDistVertical = (new Vector3(0, touch.deltaPosition.y, 0) - new Vector3(0, startPos.y, 0)).magnitude;
if (swipeDistVertical > 0)
{
float swipeValue = Mathf.Sign(touch.deltaPosition.y - startPos.y);
if (swipeValue > 0 || swipeValue < 0)//up swipe
{
vertical = true;
horizontal = false;
}
}
float swipeDistHorizontal = (new Vector3(touch.deltaPosition.x,0, 0) - new Vector3(startPos.x, 0, 0)).magnitude;
if (swipeDistHorizontal > 0)
{
float swipeValue = Mathf.Sign(touch.deltaPosition.x - startPos.x);
if (swipeValue > 0 || swipeValue < 0)//right swipe
{
horizontal = true;
vertical = false;
}
}
if(vertical)
{
transform.Rotate(touch.deltaPosition.y * 0.3f, 0,0,Space.World);
}
if(horizontal)
{
transform.Rotate(0,touch.deltaPosition.x * 0.3f,0,Space.World);
}
break;
}
}
}
I got this code from this link
Right now I can rotate, but it rotates on the z-axis aswell which I don't want. And it doesn't handle the vertical swipe right, it switches between both instead of recognizing that it is vertical right now.
I use Unity 4.6.2 and this should work on iOS and Android.
Add following code before where you've put "break".
float z=transform.rotation.z;
transform.Rotate(0,0,-z);
I have a RelativeLayout (params = MatchParent,MatchParent) as my content view.
The RelativeLayout contains a ScrollView (params=Wrap_Content, Wrap_Content).
The ScrollView then contains a LinearLayout ( no params, set vertical orientation).
To the LinearLayout I'm adding "myrows".
Each myrow is made up of another LinearLayout (no params, horizontal orientation) which contains a SpannableString which contains equally spaced/padded numbers.
The result is a vertically scrollable table, and looks ok. The problem is that if I run it on a smaller device, the SpannableStrings extend out of the screen.
On the smaller screen I want the text to be large enough to read, and so I need to be able to scroll horizontally as well to see the part of the SpannableString which has extended beyond screen. I have tried a couple of solutions already. One was to put the vertical ScrollView inside a horizontal ScrollView and capture the xy etc...but people mentioned this is dangerous. I don't want the strings to wrap. I can't use a dropbox etc...to show the beyondcreen values. It has to be a flat table with text large enough to read, I can't eliminate any of the string length.
I can make it instead a horizontal ScrollView and put a page up/down button but it won't work as smooth as it does now. Could I put a ListView inside a horizontal ScrollView and be able to scroll in both directions?
Any other ideas for this? Is there a scroll bar I can put at the bottom that scrolls the screen horizontally where it only captures your finger touch on the bar itself?
Thanks!
I finally found a solution which works great. Create a custom gridView with the following overrides. I also created a scrolling header which follows the scroll of the gridView.
#Override
public boolean onInterceptTouchEvent (MotionEvent ev) {
getMaxLeftScroll();
myLastX = ev.getX();
myLastY = ev.getY();
return super.onInterceptTouchEvent(ev);
}
#Override
public boolean onTouchEvent(final MotionEvent ev){
final int action = ev.getAction();
final float x;
final float y;
switch (action) {
case MotionEvent.ACTION_MOVE:
// This handles Scrolling only.
x = ev.getX();
y = ev.getY();
final int deltaX = (int) (myLastX - x);
final int deltaY = (int) (myLastY - y);
if(Math.abs(deltaX) > Math.abs(deltaY)) {
if( (iCurrentLeftScroll+deltaX) > 0 &&
iCurrentLeftScroll+deltaX < iMaxLeftScroll) {
scrollBy(deltaX, 0);
//Listener and call the method here to scroll the header
mScrollChangeListener.onGridViewScrolled(deltaX);
iCurrentLeftScroll+=deltaX;
} //Scrolled by some value
// Close to right edge within 10? Smooth Scroll remaining small distance if not already there
else if(deltaX > 0 && (iCurrentLeftScroll<iMaxLeftScroll)) {
if ((iMaxLeftScroll - iCurrentLeftScroll) < 10) {
scrollBy(iMaxLeftScroll-iCurrentLeftScroll, 0);
mScrollChangeListener.onGridViewScrolled(iMaxLeftScroll-iCurrentLeftScroll);
iCurrentLeftScroll = iMaxLeftScroll;
}
}
// Close to left edge within 30? Smooth Scroll remaining small distance if not already there
else if(deltaX < 0 && (iCurrentLeftScroll>0)) {
if ((iCurrentLeftScroll) < 10) {
scrollBy(iCurrentLeftScroll*-1, 0);
mScrollChangeListener.onGridViewScrolled(iCurrentLeftScroll*-1);
iCurrentLeftScroll = 0;
}
}
//left and right are subjective
if(iCurrentLeftScroll == iMaxLeftScroll)
iScrollStatus = SCROLLED_FULL_LEFT;
if(iCurrentLeftScroll == 0)
iScrollStatus = SCROLLED_FULL_RIGHT;
if( (iCurrentLeftScroll > 0) && (iCurrentLeftScroll < iMaxLeftScroll) )
iScrollStatus = 0;
Log.d(TAG," Scroll Status " + String.valueOf(iScrollStatus) );
Log.d(TAG," MaxLeftScroll " + String.valueOf(iMaxLeftScroll) );
Log.d(TAG," Current Left Scroll " + String.valueOf(iCurrentLeftScroll) );
}
myLastX = x;
myLastY = y;
break;
}
return super.onTouchEvent(ev);
}
I'm having a problem with my pointer for my tablet. I'm designing an art app and I'm trying to figure out how to mirror my movement (symmetry). Currently, if you touch the screen with your finger or stylus, an image (programmatically generated circle) is drawn and updates itself to wherever you move your finger/stylus. This works perfectly. But now I want to add two new features: Horizontal and vertical symmetry. So if you choose horizontal symmetry, another pointer will appear at the opposite X position, but along the same Y axis. So if you touch at 300x, 250y, and another pointer will show at -300x, 250y on the screen along with the original pointer. Now when I tried to apply and test it, I still only get the original pointer. Here is what I have so far:
rLO.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// Hardware accelerated at runtime
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
cursor.x = (int)event.getX() - (cursor.radius / 2);
cursor.y = (int)event.getY() - (cursor.radius / 2);
cursor.onDraw(cursor.e);
rLO.addView(cursor);
if (hSym > 0) {
vSym = 0;
cursorH.x = -cursor.x;
cursorH.y = cursor.y;
cursorH.onDraw(cursorH.e);
rLO.addView(cursorH);
}
if (vSym > 0) {
hSym = 0;
cursorV.x = cursor.x;
cursorV.y = -cursor.y;
cursorV.onDraw(cursorV.e);
rLO.addView(cursorV);
}
break;
case MotionEvent.ACTION_MOVE:
// Hardware accelerated at runtime
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
//update pointer to new position of stylus/finger
cursor.x = (int)event.getRawX() - (cursor.radius / 2);
cursor.y = (int)event.getRawY() - (cursor.radius / 2);
rLO.removeView(cursor);
rLO.addView(cursor);
if (hSym > 0) {
cursorH.x = -cursor.x;
cursorH.y = cursor.y;
rLO.removeView(cursorH);
rLO.addView(cursorH);
}
if (vSym > 0) {
cursorV.x = cursor.x;
cursorV.y = -cursor.y;
rLO.removeView(cursorV);
rLO.addView(cursorV);
}
break;
case MotionEvent.ACTION_UP:
if (vSym > 0 || hSym > 0) {
rLO.removeView(cursorH);
rLO.removeView(cursorV);
}
rLO.removeView(cursor);
break;
} // end switch
NOTE:
I used the word "cursor" in the code for "pointer." The pointer (cursor) is programmatically drawn from a different class which creates a circle.
It's probably working, but the problem is that your screen's top left is (0,0). Any negative position is off the screen. Instead divide the screen width or height in half mirror across that.