Horizontal Scroll View working unexpectedly - java

I am trying to create a calculator. I am working in the latest Android Studio. Like in calculators, all new tokes(numbers, operators) should be shown in the right and if the field is larger than the display, it should scroll to the latest token. I have already browsed and found a way to do the same.
The code for the same is:
private void scrollRight() {
horizontalScrollView = (HorizontalScrollView) findViewById(R.id.horizontalScrollView);
ViewTreeObserver viewTreeObserver = horizontalScrollView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
horizontalScrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
horizontalScrollView.scrollTo(entry.getWidth(), 0);
}
});
}
scrollRight is called by a onClick event which checks if a token is entered and calls this.
Everything is working perfectly, i.e. on every new token the scroll bar is scrolling to the end. But if I try to scroll to the beginning manually, it no longer works. After this every time a new token is pressed, the scroll bar first moves to the end and then back to the beginning.
The only option that remains is to restart the program. I tried debugging the OnGlobalLayout function but the debugger loses all frames while stepping out from the function, so it is difficult to know what exactly is making the scroll bar go to the beginning.
GIF to show the problem:
Please Help!

Try
horizontalScrollView.post(new Runnable() {
#Override
public void run() {
horizontalScrollView.fullScroll(View.FOCUS_RIGHT);
}
});
And call findViewById only once in onCreate.

Related

How to take a screenshot of a GridLayout and then share it

I have bingo app where there is a GridLayout showing all the numbers done, left.
I want to take a screenshot of it and then share it.
I have tried many posibillities and tried to do many thing, but none of them worked
case R.id.share:
//the answer should be here
the name of the GridLayout is gridLayout
if you need any other code of explanation, please tell me
Considering that we want to take the screenshot when a button is clicked, the code will look like this:
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Bitmap bitmap = takeScreenshot();
saveBitmap(bitmap);
}
});
Calling getDrawingCache(); will return the bitmap representing the view or null if cache is disabled, that’s why setDrawingCacheEnabled(true); should be set to true prior invoking getDrawingCache().
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
This code is from this website
The website also contains the code to save the screenshot taken.
Also question is possible duplicate of how to take a screen shot on a button click can anyone provide a android code

When does image.setImageResource() set the image resource inside a function?

Goal: To click on an image in an app and get it to fade out to make a different image appear.
My Method: To make the 1st image fade away after 2000ms and AFTER THAT change the image resource of the 1st image to the 2nd image to make the 2nd image appear
I have a correct solution which was provided by my instructor, so I dont want any correct solution for this. What i want to know is why is my solution not working, i.e why is setImageResource() setting the Image1 to Image 2 at the beginning despite calling it at the end
This is the fade function i have created which the image1 goes to when it is clicked
public void fade(View view){
ImageView image1 = findViewById(R.id.image1);
image1.animate().alpha(0f).setDuration(2000);
image1.setImageResource(R.drawable.cat2);
}
Actual Output: Image 1 changes to Image 2 as soon as I click it and then Image 2 fades away
Problem: Inspite of calling setImageResource() at the end of the code, it actually sets the image resource at the beginning
You are never telling image1.setImageResource(R.drawable.cat2); wait for 2000 millisecond and execute, So image2 appears as soon as you click it.
Solution:
Call image1.setImageResource(R.drawable.cat2); After 2000ms
new Handler().postDelayed(() -> {
image1.setImageResource(R.drawable.cat2);
}, 2000);
This may help.
The animation is asynchronous in your code - it doesn't block/wait, but starts the animation (or rather, queues the animation to be started) and then immediately executes the next line, which sets the image. If you want to update your image once the animation is complete, you can use withEndAction and supply a callback.
image1.animate()
.alpha(0f)
.setDuration(2000)
.withEndAction(new Runnable() {
#Override
public void run() {
image1.setImageResource(R.drawable.cat2);
}
})
.start();
I think this will be help to you:
Fade In Fade Out Android Animation in Java
so use in onClickListener like this:
image1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
image1.setVisibility(View.GONE);
//Animation...
image2.setVisibility(View.VISIBLE);
}
});

Android - View.animate skipping

I'm working on animating a View from within a GridLayout. When I access the view from the View.OnClickListener onClick(View view) method the animation runs smoothly.
However, when I get Views via gridLayout.getChildAt(i) the animation skips straight to the ending position.
view.animate()
.translationX(viewAnimation.xTransform)
.translationY(viewAnimation.yTransform)
.setDuration(200)
.setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
//Code
}
#Override
public void onAnimationEnd(Animator animator) {
if (reloadGrid)
//Code
else
animate(viewAnimations);
}
//Other methods here
});
I'm really unsure as to why when the View is passed as a parameter it animates fine, however otherwise it skips.
Any advice would be great!
Edit
I have also checked and the difference between the 2 'View' objects is one has mDrawable set and one doesn't. I believe this could be the cause?
I'm not really sure why this solves the problem, however accessing each View within the GridLayout via findViewById(i) seems to work, and then allow the animation to run smoothly.
This took way too long to figure out.

RecyclerView: Disable scrolling caused by change in focus

TL;DR I have a RecyclerView of EditTexts. When the user is focused on EditText #1 and taps on EditText #2, I want EditText #2 to get focus but I don't want the ReyclerView to scroll. How can I achieve this?
I'm trying to work with a RecyclerView populated with a bunch of EditTexts. When I'm focused on one EditText and I click on another, the RecyclerView scrolls so that the second is at the top of the screen. I want to disable this auto-scrolling from the RecyclerView, but I still want the user to be able to scroll, and I still want the second EditText to be focused on so the user can start typing. How can I achieve this?
I've already tried the following solutions:
https://stackoverflow.com/a/8101614/4077294, but with a RecyclerView.OnItemTouchListener. I called recyclerView.requestFocusFromTouch in onInterceptTouchEvent.
Behavior: Scrolled to the top of the tapped EditText all the time.
Clearing the focus from any EditText whenever it was focused on, via
editText.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, bool hasFocus) {
if (hasFocus) {
v.clearFocus();
}
}
});
Behavior: The keyboard never showed up, and the RecyclerView still scrolled to the top.
Disabling scrolling altogether as in this question is not acceptable because I still want the user to be able to scroll.
I ended up with this solution from #pskink:
recylerView.setLayoutManager(new LinearLayoutManager(this) {
#Override
public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect, boolean immediate) {
return false;
}
});
It seems to work perfectly, but #pskink has mentioned that this could have problems when using arrow keys. He's posted another solution here: https://pastebin.com/8JLSMkF7. If you have problems with the above solution, you may try the alternative solution at the link. For now, I'm sticking with the one I just posted here.
UPDATE
Since support-library v25.3.0 you should also override another requestChildRectangleOnScreen method in LayoutManager:
#Override
public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect, boolean immediate, boolean focusedChildVisible) {
return false;
}
RecyclerView will scroll to focused item.
Try recyclerView.setFocusable(false).
This worked for me.

RecyclerView programmatically click

I'm trying to programmatically click on an item of a recyclerView. I'm using:
recyclerView.findViewHolderForAdapterPosition(index).itemView.performClick();
This perfectly works when the index is of a visible item. If the item is not visible (at the last position of the recyclerview, for istance), an Exception is thrown.
What can I do?
I just had a similar question with yours.And I had solve it! Here is what I did.
xxx.mRecyclerView.postDelayed(new Runnable() {
#Override
public void run() {
xx.mRecyclerView.scrollToPosition(position);
}
},300);
xxx.mRecyclerView.postDelayed(new Runnable() {
#Override
public void run() {
xxx.mRecyclerView.findViewHolderForAdapterPosition(position).itemView.performClick();
}
},400);
}
You can scroll to the specific item, then perform click.
Because the doc say
If the item at the given position is not laid out, it will not create a new one.
But I know the adapter has the data, so scroll to it first, and findViewHolderForAdapterPositionwill not be null.
One more thing, I do not know how you use the RecyclerView. In my application, I use it in a fragment, and I don not know why we should delay it scroll and perform click. (Maybe it is because of the life circle?).But this really works.
You could call onClick directly, assuming that view manages its own click listener.
View view = recyclerView.findViewHolderForAdapterPosition(index).itemView;
view.onClick(view);
If the click listener is located somewhere else, you just need to get a reference to the object with the onClick method and call it with the correct view as a parameter.
try this for kotlin and viewBinding
viewBinding.catList.post {
val view = viewBinding.catList.findViewHolderForAdapterPosition(0)?.itemView?.findViewById<CheckBox>(R.id.catButton)
view?.callOnClick()
}

Categories

Resources