Android listview scroll by pixels with no delay - android

I have a listview that I am implementing pinch zooming on. I resize each child view of the listview which changes the row height. When these rows are resized, the top item of the list view remains stationary and the items below it move up to recover the slack space.
I'm trying to implement the pinch zoom in 2 parts. First, make the zoom origin the center of the visible list (right now it's the top, like I said). Second, adjust the origin based on the focal point of the zoom gesture.
My problem is that I can't smoothly adjust the origin of the zoom. The method I have right now does scroll the list, but it does it a few milliseconds after the view is updated (it actually looks pretty bad... It's really choppy).
Is there a better way to do what I'm doing in the code below?
mMsgs is a listview.
// Center align the scroll
int yviewspace = mMsgs.getHeight();
int newyviewspace = (int) (yviewspace * zoomratio);
//mMsgs.scrollBy(0, -(yviewspace - newyviewspace) / 2); //This is smooth, but, sadly, it doesn't work on listviews.
mMsgs.smoothScrollBy(-(yviewspace - newyviewspace) / 2, 0);

Related

Android - Canvas not drawing after Translation?

I am working on a custom view where i draw lines horizontally one after another left to right. When the collective width of all the lines combined crosses the width of the view , i translate the view. After translating the view , the view moves leftward , but canvas.drawLine stops drawing lines as soon as i translate the view. Any solution to this problem?
for(someCondition){
canvas?.drawLine(startX,startY,stopX,stopY,linePaint)
if(startX > (width)){
log("Invisible , setting translation to ${-(startX - width)}")
translationX = -(startX - width)
}
log("width is $width and startX is $startX")
}
as soon as i translate , the canvas stops drawing but translate keeps happening.
I solved the problem without having to translate anything.
Everytime the collective width of the lines crossed the width of the View , i increased the starting index of the array so that i drew only n elements, where n is the max number of lines that can fit inside the views width. This solution also helped avoid drawing unnecessary lines everytime a new element was added to the array.

Finger selection UI screen

I am creating layout for finger selection. In this I am trying to achieve click events for each individual finger. This layout should be uniform on any type of screen resolution.
My approach:
Inside relative layout, I am assigning radio buttons (not radio group but individual) to each finger inside hand image using margins and padding but it is not resting properly over finger image. They are slightly moving left or right.
Problem in this - radio button positions is changing if screen resolution changes.
I failed to find library for such click events. Also in SO I didn't find any related questions. Can someone guide me in this to library or example or better approach than this?
A several years ago I worked on the similar task. Unfortunately, I don't remember the whole solution, but idea was pretty simple. In my case it was an image of the map where a user could select a district by tapping the map. I knew the resolution of the original image that I used to display in UI. I encoded each district against its boundaries so it gave me a list of pair's number. I had a touch listener attached to ImageView that was used to display the map. So every time a user clicked on the map I got a position of his click, multiply this value by a scale factor(this one was calculated based on the size of original image and the one that was scaled by Android). Then I checked if that value laid in any polygons.
So to make it more clear:
Let width, height = size of original image
x, y = user touch
scaleWidth, scaleHeight = size of the image displayed by Android on the user device
scaleX = scaleWidth / width, scaleY = scaleHeight / height
originalX = scaleX * x, originalY = scaleY * y
Then check if originalX and originalY fits in polygons. In your case those polygons could be just squares around every finger.

setRotation() on RecyclerView's parent causes lag

For a pure design stuff I need to perform some animation on a RecyclerView Parent. These animations include a scale and a rotation on Y axis. When recyclerview is not populated everything is okay, but if I add some elements (not so much) animation become very laggy. I suppose because on each frame the recyclerview tries to refresh all its view even if nothing in the adapter has changed.
This is the code I use to animate the parent:
final float scale = 1 - 0.3f * slideOffset;
panel.setPivotX(0);
panel.setPivotY(panel.getHeight() / 2.0f);
panel.setScaleX(scale);
panel.setScaleY(scale);
float angle = -slideOffset * MAX_ROTATION_ANGLE;
panel.setRotationY(angle);
'panel' is my custom layout view where is located the recyclerview plus other views, 'slideOffset' is a float between 0-1 defined by user's finger on the screen.
I've tried also:setHasStableIds(true);to the adapter but nothing changed, and even setLayerType(View.LAYER_TYPE_HARDWARE, null);doesn't help.

Set PDFViewCtrl scroll to an absolute position in the document

I'm using the Android version of PDFNet 6.5.0.
I need to set the vertical scroll of the PDFViewCtrl to an absolute point in the pdf, expressed in PDF Canvas coordinates.
For example, say that I want to zoom to the middle of the second page.
I could get the y coordinate, in PDF Canvas position like:
int y = doc.getPage(1).getPageHeight() + (doc.getPage(2).getPageHeight() / 2)
How could I scroll to the y position?
I'm trying to do it with PDFViewCtrl#setVScrollPos(), but I don't know how to convert y to a valid parameter for this method.
Have you tried to use PDFViewCtrl#scrollTo(int, int)?
i.e. first convert points from PDF space to canvas space(PDFViewCtrl#convPagePtToCanvasPt), then scrollTo the position.
Although I have accepted Shirley G's answer I am posting this other answer for clarification.
The tricky bit is which number to pass as parameter to PDFViewCtrl#setVScrollPos(int) or PDFViewCtrl#scrollTo(int, int)
You need to use PDFViewCtrl#convPagePtToScreenPt() to convert the page position into a physical screen point.
But you also need to take into account the current scroll offset of the scroll view pdfViewCtrl#getVScrollPos()
So, given you want to scroll to verticalPosition in page:
public void scrollToDocPosition( final int verticalPosition, final int page) {
double[] screenPos = pdfViewCtrl.convPagePtToScreenPt(0, verticalPosition, page);
pdfViewCtrl.setVScrollPos((int) screenPos[1] + pdfViewCtrl.getVScrollPos());
}
I came to this thanks to https://groups.google.com/forum/?fromgroups#!searchin/pdfnet-sdk/scroll/pdfnet-sdk/7Wy00goWfyQ/t1tvApNDrr8J, where Thomas Hoffman explains:
The first thing to look at is the scroll position. y after
converting is in screen space, while SetX/YScrollPos is in the
coordinates of the scroll viewer. That is, the top left corner of the
PDFViewCtrl is at position (0, 0) in screen space, but at position
(GetHScrollPos and GetVScrollPos) in scroll coordinates

TouchUtils.dragViewToX will only scroll in one direction

I can easily use the following code to scroll the view to the left using
TouchUtils.dragViewToX(this, myView, Gravity.LEFT, -1000);
It will even just sit there for a second if it can't scroll anymore, like it's still trying to, which is the expected behavior, so the contents of the view shouldn't be the issue.
But if I do the opposite, it acts as though it's not even there.
TouchUtils.dragViewToX(this, myView, Gravity.LEFT, 1000);
It doesn't even pause for a second to simulate the dragging like the other one will no matter what. It even returns the propper pixel value for distance covered! Why will it only listen to this function when it's supplied with a negative value? Why will it not drag in the opposite direction?
It's not even a positive/negative issue, it will scroll to the left if I supply a positive value and a different Gravity (like RIGHT or END), but no matter what it won't scroll to the right.
First of all, dragViewToX will try to drag the view you specify to the X-coordinate you specify.
The Gravity field specifies which part of the view is to be dragged.
So I'd suggest you use the rect values rather that using hard coded coordinates so that the test will work independent of the device specification. Here's a sample code.
View view = sListView.findViewById(R.id.foo);
Rect rect = new Rect();
view.getHitRect(rect);
TouchUtils.dragViewToX(this, view, Gravity.CENTER, rect.left); // To drag left. Make sure the view is to the right of rect.left
TouchUtils.dragViewToX(this, view, Gravity.CENTER, rect.right); // To drag left. Make sure the view is to the left of rect.right
The only thing that is wrong with your code is that the value 1000 is already out of the screen and therefore there is no where to drag to :)

Categories

Resources