I want my app to only expand the app bar after pulling the screen 2 times when it reaches the beginning of the scroll
Example
EDIT:
I will try to improve the question. How do I get the starting position of a recycle view or a viewpager2. So when the position is 0 (Starting position), I want the appbar not to expand, now to expand it has to pull down while in position 0
I got it through the following commands
AtomicBoolean firstBoot = new AtomicBoolean(true);
recycleView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
if (firstBoot.get) {
firstBoot.set(false);
return;
}
if (recyclerView.computeVerticalScrollOffset() == 0){
recyclerView.stopScroll();
bar.setExpanded(false);
}
}
});
The variable "firstBoot" is so that the method is not executed when the activity is created
Related
I want to use right and left buttons to scroll items with like 10 items
I tried to use scrollBy but it did not work
Here is my Layout Image.
I want to be able to scroll right and left
You can use for Next button:
mRecyclerView.getLayoutManager().scrollToPosition(linearLayoutManager.findLastVisibleItemPosition() + 1);
And for Previous Button:
mRecyclerView.getLayoutManager().scrollToPosition(linearLayoutManager.findFirstVisibleItemPosition() - 1);
Have look this
You can have a variable that tracks the current displayed position of the RecyclerView, named it "currentPosition" in below snippets
Then increment it if you want to navigate to the next item as follows:
private void scrollToNext() {
if ((recyclerView.getLayoutManager()) != null) {
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(currentPosition++, 0);
}
}
You can use RelativeLayout or the custom layout instead of LinearLayout; according to what you're using in your RecyclerView
Similarly, decrement it if you want the previous one
private void scrollToPrevious() {
if ((recyclerView.getLayoutManager()) != null) {
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(currentPosition--, 0);
}
}
I have an arraylist of custom objects. Each custom object corresponds to a modal inside a scroll view in my application. If there are 5 "timecard" objects in my array list, there will be 5 modals stacked vertically.
The ultimate behavior I would like, is if I have a vertical stack of 5 cards, I would like to animate the first card, when finished, start the second, when finished, do the third, etc.
Here is my method:
public void inflatetimeCardContainer(){
timecardContainer.removeAllViews();
int tclistIndex = 0;
for(TimeCard tc : timeCardList){
timeCardFragment = (RelativeLayout)LayoutInflater.from(this).inflate(R.layout.timecard_fragment, timecardContainer, false);
textViewTitle = (TextView)timeCardFragment.findViewById(R.id.textViewTitle);
textViewHours = (TextView)timeCardFragment.findViewById(R.id.textViewHours);
textViewPay = (TextView)timeCardFragment.findViewById(R.id.textViewPay);
textViewNotes = (TextView)timeCardFragment.findViewById(R.id.textViewNotes);
buttonDelete = (Button)timeCardFragment.findViewById(R.id.buttonDelete);
buttonDelete.setOnClickListener(handleButtonDelete);
buttonDelete.setId(tclistIndex++);
textViewTitle.setText(tc.getTitle());
textViewHours.setText("Hours: " + String.valueOf(tc.getHours()));
textViewPay.setText("Pay after taxes: " + String.valueOf((tc.getHours()*tc.getPayRate())*0.77));
textViewNotes.setText(tc.getNotes());
timeCardFragment.setAlpha(0);
timecardContainer.addView(timeCardFragment);
timeCardFragment.animate().alpha(1.0f);
// SOME KIND OF PAUSE HERE UNTIL ANIMATION IS DONE
// One the animation is done, continue in my for loop
}
}
Consider using a RecyclerView and an ItemAnimator
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ItemAnimator.html
I have a GridView which contains several items. By clicking an item a new detail view is created. Then by clicking back button user is returned to GridView. I want to preserve exact scroll position and I have accomplished that with following code:
Creating GridView
mArtistList = (GridView) artistsView.findViewById(R.id.gridview);
mArtistAdapter = new ArtistAdapter(mContext);
mArtistList.setAdapter(mArtistAdapter);
// Adapter gets items asynchronously
mArtistAdapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged () {
// setting first selection item
mArtistList.setSelection(sActiveItem);
/*
*
* PROBLEM HERE
* Works ok, but when user touches the GridView
* scroll position jumps to position where it
* would be without this line.
*
*/
mArtistList.scrollBy(0, sActiveTop);
super.onChanged();
}
});
When user clicks an item on GridView
sActiveItem = mArtistList.getFirstVisiblePosition();
// vertical spacing (5dp to pixels)
sActiveTop = (int) (5.0f * getResources().getDisplayMetrics().density);
View firstItem = mArtistList.getChildAt(0);
if (firstItem != null) {
sActiveTop -= firstItem.getTop();
}
This works fine. Scroll position is exactly right after back button is pressed. The problem comes when user touches GridView. Scroll jumps to position where the first visible item is exactly at top of screen. How can I prevent this jump?
I don't speak english as my native language, so my explanation might be hard to understand. That's why I draw an image to indicate the problem:
I am currently working on custom animation between switching pages in ViewPager. When I slide to the left, View is moving to the left and from below of it new View is coming to the front. I would like to make the view, that moves to the left (that I dispose) to shrink like on the folowing images:
On the second and third image I didn't picture new View coming to the front, but I think it wasn't necessary. Do you have any idea how can I modify the code? I would like to change height of TableLayout, RelativeLayout and FrameLayout and keep the height of both TextViews. Also I would have to change X-position of the whole View. I am looking forward for your creative answers (code). Below I attach my code for the animation.
import android.view.View;
import android.widget.RelativeLayout;
import android.annotation.SuppressLint;
import android.support.v4.view.ViewPager.PageTransformer;
public class DepthPageTransformer implements PageTransformer {
private static float MIN_SCALE = 0.75f;
#SuppressLint("NewApi")
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
//float scaleFactor = (1 - Math.abs(position));
//WHAT TO PUT HERE TO ARCHIVE MY GOAL??
//This is how I can get particular layouts:
// RelativeLayout relativeLayout = (RelativeLayout) view.findViewById(R.id.fragment_object_canvas_RelativeLayout1);
//relativeLayout.setScaleX(scaleFactor);
//relativeLayout.setScaleY(scaleFactor);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
//view.setRotation(1 - (position*360));
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
UPDATE:
I can manipulate with height of whole View (for now I can do only this) with the following code:
LinearLayout relativeLayout = (LinearLayout) view.findViewById(R.id.fragment_object_canvas_linearLayout1);
relativeLayout.setLayoutParams(new FrameLayout.LayoutParams(relativeLayout.getWidth(), NEW_HEIGHT_HERE)));
However, I am not sure what should I put into NEW_HEIGHT_HERE variable to make it work corectly...
try to work with a position float variable.
Get the height of your layout and...:
relativeLayout.setLayoutParams(....,position*height+height)
You seem pretty insistent on people posting original code, but why reinvent the wheel? This library has a ton of great animations for a ViewPager, including one very similar to what you seem to be requesting.
https://github.com/jfeinstein10/JazzyViewPager
JazzyViewPager -
An easy to use ViewPager that adds an awesome set of custom swiping animations. Just change your ViewPagers to JazzyViewPagers and you're good to go!
public enum TransitionEffect {
Standard,
Tablet,
CubeIn,
CubeOut,
Flip,
Stack,
ZoomIn,
ZoomOut,
RotateUp,
RotateDown,
Accordion
}
You can select your animation by calling
private JazzyViewPager mJazzy;
/* ... */
mJazzy.setTransitionEffect(TransitionEffect.*);
I am trying to accomplish following things
Suppose I have 5-6 TextViews with values S N A K E
Now, I want to press S textView then slide my finger over N to select it too and then move my way to E. I want to do that so that i can get "SNAKE" in my string or char sequence etc
If there is any idea do share me. I can't get it how to use onTouch here.
Also, i am adding textViews dynamically so i am setting their ids dynamically too
Best Regards
I've never done this, but here's a thought.
Assuming all your textviews are in some sort of layout, you could disable the focusability on your textview and create an onTouch listener on your underlying container.
Start tracking on Mouse Down events
#Override public boolean onTouch(View v, MotionEvent event) {
if(event.getAction == MotionEvent.ACTION_DOWN)
{
captureInput = true;
}
}
*On your ACTION_MOVE event, check if the current position is above a textview, if so, capture that value*
#Override public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if(action == MotionEvent.ACTION_DOWN)
{
captureInput = true;
}
else if(action == MotionEvent.ACTION_MOVE
{
//get x/y of your finger
int X = (int)event.getX();
int Y = (int)event.getY();
//Somehow check if the x,y are overlapping with one of your textivews
// If so, add that textview's text to your list
// Below is pseudo code
/* for(TextView curTV: allTextViews)
{
if(isOverlapping(X,Y))
{
listOfSwipedCharacters.add(curTV.getText());
}
}
}
}
Lastly, when the user releases their finger, stop tracking and do something with the word list
#Override public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if(action == MotionEvent.ACTION_DOWN)
{
captureInput = true;
}
else if(action == MotionEvent.ACTION_MOVE
{
//get x/y of your finger
int X = (int)event.getX();
int Y = (int)event.getY();
//Somehow check which textview the X,Y coords are overlapping
// Below is pseudo code
/* for(TextView curTV: allTextViews)
{
if(isOverlapping(X,Y))
{
listOfSwipedCharacters += (curTV.getText());
}
}*/
}
else if(action == MotionEvent.ACTION_UP)
{
captureInput = false;
//Do whatever you want with the string of information that you've captured
}
}
Once again, I have no idea if that will work, it's just a guess at an approach. I suspect performance of cycling through each textview to check for overlaps will be pretty crappy, so there may be a more efficient approach than running a for loop.
Since you know you can't jump over letters when swyping, you could create a short list of all the possible swipe locations (surrounding letters) whenever you add a new letter. Then on your mouse event, check if any of those letters have been hit by the mouse move event. For example, in a standard word search game, once you select a letter, there are only 9 other possible locations for you to swipe (the surrounding letters), so you should only bother checking if those 9 locations have been hit when you capture the mouse move event.
Edit: I suppose you could use the solution above if you attached an onTouch listener to each and every textview. The same premise in regards to touch would apply: Down = start capture, move = capture text, up = stop capture. It would save you from having to identify which textview is being hovered as the textview that fires the onTouch event will be the one that the user is swiping across.