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:
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 am working with a multimedia player. Where song list is shown on listView. so for example if first song is playing the first row should marked as playing and other row should unmarked. Then if user click on third or second or any other row then current row should be unmarked. And clicked row should marked. Here marked and unmarked mean Play and Pause. I do play and pause toogle with same row. But how to change the element of earlier row? Can I store View of earlier row in a View ? or anything else?
Here is the code of setOnClickListener
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ImageView imagEar = (ImageView) viewEar.findViewById(R.id.thumb);
imagEar.setImageResource(R.drawable.pause);
imagEar.setTag("pause");
viewEar = v;
if(imageView.getTag().toString().equals("play")){
imageView.setImageResource(R.drawable.pause);
imageView.setTag("pause");
}else if(imageView.getTag().toString().equals("pause")){
imageView.setImageResource(R.drawable.play);
imageView.setTag("play");
}
}
});
I already declared View viewEar;
Hi check the below url for more understanding on your requirement.
Basically you have to take one variable says selectedPosition upon on clicking item you change change the selectedPostion value and by using that u can apply changes on that view and by calling notifySetChanged() which refresh the list.
http://www.devexchanges.info/2015/11/listview-with-checkbox-single-row.html
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 am using jeremy feinstein's SlidingMenu for an Android app. When the left menu is opened, I still have a remaining space from the behind view uncovered. In that remaining view I have a button that I want to handle onClick. But when I click on it or in any other part of the view, it just closes the left menu.
How can I make this work? I tried to set sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN|SlidingMenu.TOUCHMODE_FULLSCREEN); but it didn't work this way. This is the code for my SlidingMenu object:
SlidingMenu sm = getSlidingMenu();
sm.setShadowWidthRes(R.dimen.shadow_width);
sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
sm.setFadeDegree(0.0f);
sm.setMode(SlidingMenu.LEFT_RIGHT);
sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN|SlidingMenu.TOUCHMODE_FULLSCREEN);
// set the left menu
sm.setMenu(R.layout.menu_frame_left);
getSupportFragmentManager().beginTransaction()
.replace(R.id.menu_frame_left, new LeftMenuListFragment())
.commit();
// set the right menu
sm.setSecondaryMenu(R.layout.menu_frame_right);
getSupportFragmentManager().beginTransaction()
.replace(R.id.menu_frame_right, new RightMenuListFragment())
.commit();
I will also attach an image drawn by me to explain better what I am trying to achieve:
Based on the code of jeremy feinstein's SlidingMenu, I found number value on the constant value for use with setTouchModeAbove() :
/** Constant value for use with setTouchModeAbove(). Allows the SlidingMenu to be opened with a swipe
* gesture on the screen's margin
*/
public static final int TOUCHMODE_MARGIN = 0;
/** Constant value for use with setTouchModeAbove(). Allows the SlidingMenu to be opened with a swipe
* gesture anywhere on the screen
*/
public static final int TOUCHMODE_FULLSCREEN = 1;
while you set sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN|SlidingMenu.TOUCHMODE_FULLSCREEN); ,in fact the vaule of touchModeAbobe is 1|0 that equal 1 .
I suggest you try sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);,it may work.
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.*);