I've been trying to implement an activity where I can scroll horizontally and vertically in all directions, I've tried out using gesturelistener and the "scrollby" method in View, however the screen is still static. I've also done a nested horizontal and vertical scroll in xml, however this only gives me scrolling to the right of the screen and bottom. It seems i cant move in the negative x direction.
Thanks.
Customize ViewGroup
Override OnTouchEvent
Detect MotionEvents
Track Finger Points
Calculate Distance Moved
Modify the X and Y of the canvas Content Rectangle.
Finally in your layout add child views you want to scroll inside this ViewGroup
Source code: https://gist.github.com/jayakrishnan-pm/ScrollingLayout.java
Related
I have a relative layour and a imageview inside of it. I want to move the imageview to the touch position.
I have tried these methods for X and Y
view.setX()
view.setTranslationX()
view.setTop()
view.animate().x()
none of them is working, nothing happens.
The code runs inside PagerAdapter. I have an imageview that takes all screen and i set onTouchListener for it, get touch coordinates and set them to another imageview, that is a red circle, to move it to the touch location, but it is not moving at all.
my question is related to android feature to zoom the parent consisting of multiple child view's.
ZoomView->ParentView->[multiple childViews]
I am working on a Demo project to Zoom the child View and to pan infinitely.Zooming works perfectly as needed.
PROBLEM 1:
But if there is a EditText in the view and i try to zoom on that then below issues are faced by me.
on zooming in the text is blurred
pointing on a text is working fine but translating through the text is
translating very fast as its translation is multiplied by the
scalingFactor
Selecting the text is also having above issue.
Try running the the Demo to understand the issue if not clear from above
I have tried two approaches to Zoom the content of the View but both approaches gave the same issue.
Scaling canvas and transforming the MotionEvent by scaling the MotionEvent by Matrix.class of the Parent Class.
Setting ScaleX and ScaleY of the Parent containing the childViews
hierarchy of my demo project zooming the view(UML Diagram)
Basic problem is placing the cursor at the right position when the view is scaled to some value.
I have already referred to this thread
PROBLEM 2:
if i have a childView which is movable in the parent View then after zooming out if the childView is translated outside the bounds of parentView the events are ceased to capture and the child view becomes untouchable
i have tried using TouchDelegate but i don't know how to expand the parentView touch area .Code reference Thread
scale is 1 the area touch area is equal to screen for parentView and ZoomView
But when scale factor is not equal to one the touch area of parent is lesser(zoomIn) than the ZoomView as displayed
Yellow-parentView Touch Region
Cyan-ZoomView Touch Region
Green-ChildView Touch Region
ScreenShot here
Note:
This is my first Question on StackOverflow So please recommend if some edits are needed.
This the the closest i got to solve above problem's.
PROBLEM 1:
On zooming in the text is blurred
setLayerType(LAYER_TYPE_HARDWARE,null);
set layer type Hardware in the view which has text View. for me i
set it in green square view.
pointing on a text is working fine but translating through the text is translating very fast as its translation is multiplied by the scalingFactor
Selecting the text is also having above issue.
For above two:
This is a bug in android when you scale a view using the scaleX,scaleY api's the EditText get's event based on the current scale value of parent's.But issue is with the Cursor of editText.
The best solution we got is we wrote our own EditTextView (which extend's TextView).As we checked android framework source code we came to know that android use's PopUpWindow to display cursor on screen.
The source of issue is when we use scaleX and scaleY editText get's scaled even't as it's parent is scaled but as cursor is a PopUpWindow and not a child of EditText so event's are not scaled and above issue occur's
So wrote our own EditText if you see the source code EditText code is not very complex and can be written on our own.And to solve the scaling issue of Cursor, we added our own Cursor PopUpWindow and made it Scale aware.
NOTE:
(UPDATE)
Check at demo code here customEditText and CustomCursor.
Run the project set focus pink focus(BY Android) will come ,wait for few seconds then the black cursor will appear that is the custom cursor.
It is a very basic example and we need to add all other edit text Feature's on our own like multi-Select, popUpMenu etc.
PROBLEM 2: if i have a childView which is movable in the parent View then after zooming out if the childView is translated outside the bounds of parentView the events are ceased to capture and the child view becomes untouchable i have tried using TouchDelegate but i don't know how to expand the parentView touch area
This solution is specific to the given problem not a generic one
as there can be multiple solution's for this problem.
In this case 3 view's are there:
Yellow-parentView of green square View
Cyan-parent of yellow View
Green-ChildView non touchable outside parent
My Solution is that i used created a callback from green square view to Yellow parent view. Whenever the translation of green square view ended the callback is triggered and in yellow parent i used below code.
override fun eventEnded() {
setDelegate()
}
fun setDelegate() {
val rect = Rect()
val parent = (this.parent as View)
parent.getHitRect(rect)
val touchDelegate = TouchDelegate(rect, this)
if (View::class.java.isInstance(editorContainer.parent)) {
(editorContainer.parent as View).touchDelegate = touchDelegate
}
}
The above code translate to : when child view translation is ended check the bound's of parent and update the TouchDelegate accordingly.
As the problem i faced was when i scaled(Zoomed) the view then the View's delegate was not updated so for that also solution is same make a callback from zoomView (parent) to yellowView (childView) onScaleEnded call setDelegate().
When scale changes the hitArea also changes but as per delegate nothing is changed so we need to update the rect of TouchDelegate.
Please feel free to discuss in comment section. If someone has a better solution Really eager to know.As we tried many different solution's but nothing else worked.This is the best i found and i am using above code in production and haven't faced any issue till now.
The best approach for translating and scaling EditText is to use scaleX, scaleY, translateX, translateY on this particular EditText instead of parent layout canvas translation.
e.g. in kotlin
editText.scaleX = scaleFactor
editText.scaleY = scaleFactor
editText.translateX = offsetLeft
editText.translateŠ½ = offsetTop
By the way, it is possible to check if touch area and drawing area are the same in android studio using Tools -> Layout Inspector.
Within Android, I'm trying to move a TextView from outside the parents bounds into view, but the contents never shows up, or remains clipped if it was partially within the bounds already.
Initial situation at start
Situation after animation
(Below this is another view, that was completely out of bounds and isn't drawn either)
I have 4 TextViews below each other in a custom Object extending RelativeLayout. Based on a percentage the top 2 should move outside it's bounds and the bottom 2 should move in (from the bottom).
I use the following code to update the properties of each TextView. In this class each variable **positionY* is filled with their initial position from the layout-xml. effect is percentage between 0 & 1. The animation works, but the views aren't drawn again.
public class ActionBarTitleView extends RelativeLayout {
public void updateTransition(float effect) {
float height = getHeight();
titleView1.setY(title1positionY - height*effect);
detailView1.setY(detail1positionY - height*effect);
titleView2.setY(title2positionY - height*effect);
detailView2.setY(detail2positionY - height*effect);
invalidate();
}
}
What I tried
After some researching I found a few hints what the issue might be, but so far none of the tried options had any effect. Below is a list of things I've found on SO and tried.
Calling invalidate() on the RelativeLayout - No effect.
Invalditing the TextViews - No effect.
clipChildren = false for the RelativeLayout - No effect.
setWillNotDraw = false for the RelativeLayout - No effect. (onDraw is being called)
I haven't tried to solve this with a ScrollView, but I don't want to really, cause that adds another layer in the hierachy for something pretty small.
I thought I understood the drawing logic, but perhaps I'm missing something, so I hope someone might be able to point me in the right direction.
What I ended up doing (September 3rd)
Since no real solution was offered, I tried again and came to the following "fix". I set both second labels to Visibility.GONE, but within the original bounds of the container view. Then when I start the animation, I set their correct values, then move them outside the bounds and finally setting Visiblity.VISIBLE. When the animation progresses the labels roll into view as supposed to. So a fix to the issue, but no real explanation why the TextViews aren't drawn again...
I have a CustomeLinearlayout that allows to swipe from bottom to top or top to bottom to hide itself. In this layout, I have a custome image view that is zoomable, the problem is when I swipe top-down, bottom-up on the imageview, the layout get the touch event. I know why this happens but can not find a way to prevent it.
The code in the onInterceptTouchEvent() method of the custom linearlayout
....
case MotionEvent.ACTION_MOVE:
// check if user swipe top-bottom or bottom-top
// return true if it is, break otherwise
// The current implementation always return true if it detects user is swiping from top to bottom or bottom to top (doesnt care how its children feel)
....
My question is how to detect if user want to scroll the zoomed image rather than swipe the Linearlayout?. The Layout only handle its onTouch only if the zoom image is not zoomed (scale ratio is 1f)
If your image is zoomed then you can call requestDisallowInterceptTouchEvent(true) method
Can you draw a rectangle in a scrollview? If so how? I did some searching and I was not able to find an answer. Specifically, I want the rectangle IN the scrollview so that when I scroll the rectangle moves with the view, as opposed to a rectangle being on top of the scrollview, where the scrollview would scroll under the rectangle and the rectangle would remain on top where it is.
You need to create a class that extends ScrollView and override onDraw(). There you can draw whatever you want. To make the drawing scroll with the content, you should offset the locations with the values you get by getScrollX() or getScrollY().