How to scroll to a particular position in recyclerview inside scrollview? - android

I have searched a lot regarding my query and none of them was useful. I have a recyclerview and some static data inside a scroll view which is inside a root parentlayout as show below.
I have set -
scrollview.scrollto(0,0);
because everytime i open the activity it jumps to the recyclerview firstitem and it skips out the static data above the recyclerview.
recyclerview.setNestedScrollingEnabled(false);
recyclerview.setfocusable(false);
for smoothscroll.
the problem is with-
layoutmanager.scrollToPositionWithOffset(pos,0);
it is not working. I have set the aboveline after setting adapter to recyclerview. Also tried with NestedScrollView but in vain.
although I have used
layoutmanager.scrollToPosition(pos);
For those who skip the code, i have set match_parent to ScrollView and
fillviewport to true.
Here is my layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/bottomsheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.inkdrops.khaalijeb.BrandCouponActivity">
<RelativeLayout
android:id="#+id/inclusionviewgroup"
android:layout_width="match_parent"
android:layout_height="match_parent">
<static data/>
<ScrollView
android:id="#+id/scrollviewmain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/one"
android:fillViewport="true"
android:scrollbars="none"
android:layout_above="#+id/donelayout">
<staticdata/>
<TextView
android:id="#+id/dealstext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/card1"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:textSize="16sp"
android:text="Deals & Coupons"
android:textColor="#444444" />
<RelativeLayout
android:id="#+id/recyclerlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/dealstext"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#color/colorbackground">
<android.support.v7.widget.RecyclerView
android:id="#+id/coupon_rec_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorbackground"
android:visibility="visible"/>
</RelativeLayout>
<statisdata>
</RelativeLayout>
</ScrollView>
include layout="#layout/activity_coupons"
android:visibility="gone"
/>
</RelativeLayout>
</RelativeLayout>

Need to scroll ScrollView by getting top position of RecyclerView's child :
float y = recyclerView.getY() + recyclerView.getChildAt(selectedPosition).getY();
scrollView.smoothScrollTo(0, (int) y);

you can use scroll view method to reach your desired locations as:
scrollView.smoothScrollTo(int x, int y);

Step 1: Add this line for selecting that position in the recyclerview
adaptercat.setSelectedItem(Integer.parseInt(dealtypeid));
Step 2: Once check below constructor by getting current position
public CatgerotyAdapter(Context context, ArrayList<HashMap<String, String>> arraylist,String selectedPosition) {
this.context = context;
this.data = arraylist;
resultp = new HashMap<>();
currentItemPos=Integer.parseInt(selectedPosition)-1;
}
Step 3: And this function also in adapter
public void setCurrentItem(int item)
{
this.currentItemPos = item;
}
Last step 4. Add this function outside adapter in your class
private void onPagerItemClick2(Integer tag)
{
adaptercat.setCurrentItem(tag);
catsp.setAdapter(adaptercat);
}
Pust this line in your listview item click listner
((ClassName) context).onPagerItemClick2(position);
That position will be selected when will you open listview ..

Use this method scrollToPosition (int position) this is work for me. hope this will help you.
mMessagesRecyclerView = (RecyclerView) findViewById(R.id.messagesRecyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
mMessagesRecyclerView.setLayoutManager(layoutManager);
mMessagesAdapter = new MessagesAdapter();
mMessagesRecyclerView.setAdapter(mMessagesAdapter);
mMessagesRecyclerView.scrollToPosition(your position);
this is my layoutstructer

Related

Android RecyclerView and GridLayoutManager layout

I'm trying to implement a RecyclerView with a GridLayoutManager in my Android application. The CardView elements within the RecyclerView are displaying vertically as if they were in a LinearLayout. How can I coerce them to fill the grid from left to right, one row at a time?
Here is my RecyclerView layout code:
<android.support.v7.widget.RecyclerView
android:id="#+id/RECYCLER_VIEW"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/item_offset" />
Here is my CardView layout code:
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_view"
card_view:cardUseCompatPadding="true"
android:layout_width="120dp"
android:layout_height="120dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_alignParentBottom="true"
android:textAlignment="center"
android:textSize="18dp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
Here is the code to set up the RecyclerView in the activity's onCreate method (CustomAdapter extends RecyclerView.Adapter):
// set up adapter
adapter = new CustomAdapter(getApplicationContext(), ApplicationState.getGridElements());
view.setAdapter(adapter);
// grid layout manager with 2 columns
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
view.setLayoutManager(layoutManager);
// custom decoration for equal spacing
ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(getApplicationContext(), R.dimen.item_offset);
view.addItemDecoration(itemDecoration);
view.setHasFixedSize(true);
GridLayoutManager (Context context,
int spanCount,
int orientation,
boolean reverseLayout)
Set reverseLayout as true

Large gap forms between RecyclerView items when scrolling down [duplicate]

This question already has answers here:
RecyclerView items with big empty space after 23.2.0
(5 answers)
Closed 3 months ago.
I'm making a ToDo list app, and while testing it, for some reason, a huge gap forms between the items whenever I try to scroll down. It always happens whenever I Drag and Drop the items, but I don't see any errors with my ItemTouchHelper adapter and callback class. It would be awesome if you can help me out.
Before:
After:
RecyclerAdapter.java
public class RecyclerAdapter extends
RecyclerView.Adapter<RecyclerAdapter.RecyclerVH> implements ItemTouchHelperAdapter{
private LayoutInflater layoutInflater;
ArrayList<Info> data;
Context context;
public RecyclerAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
this.context = context;
}
public void setData(ArrayList<Info> data) {
this.data = data;
notifyDataSetChanged();
}
#Override
public RecyclerVH onCreateViewHolder(ViewGroup viewGroup, int position) {
View view = layoutInflater.inflate(R.layout.custom_row, viewGroup, false);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("R.A onClick Owen", "onClick method triggered");
}
});
RecyclerVH recyclerVH = new RecyclerVH(view);
return recyclerVH;
}
#Override
public void onBindViewHolder(RecyclerVH recyclerVH, int position) {
Log.d("RecyclerView", "onBindVH called: " + position);
final Info currentObject = data.get(position);
// Current Info object retrieved for current RecyclerView item - USED FOR DELETE
recyclerVH.listTitle.setText(currentObject.title);
recyclerVH.listContent.setText(currentObject.content);
/*recyclerVH.listTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Open new Activity containing note content
Toast.makeText(this, "Opening: " + currentObject.title, Toast.LENGTH_LONG).show();
}
});*/
}
public void deleteItem(int position) {
DBInfo dbInfo = new DBInfo(context);
dbInfo.deleteNote(data.get(position));
// Deletes RV item/position's Info object
data.remove(position);
// Removes Info object at specified position
notifyItemRemoved(position);
// Notifies the RV that item has been removed
}
#Override
public int getItemCount() {
return data.size();
}
// This is where the Swipe and Drag-And-Drog methods come into place
#Override
public boolean onItemMove(int fromPosition, int toPosition) {
// Swapping positions
// ATTEMPT TO UNDERSTAND WHAT IS GOING ON HERE
Collections.swap(data, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
return true;
}
#Override
public void onItemDismiss(int position) {
// Deleting item from RV and DB
deleteItem(position);
}
class RecyclerVH extends RecyclerView.ViewHolder implements View.OnClickListener{
// OnClickListener is implemented here
// Can also be added at onBindViewHolder above
TextView listTitle, listContent;
public RecyclerVH(View itemView) {
super(itemView);
listTitle = (TextView) itemView.findViewById(R.id.title);
listContent = (TextView) itemView.findViewById(R.id.content);
listTitle.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(context, "Opening: Note" + getLayoutPosition(), Toast.LENGTH_SHORT).show();
// PS NEVER ADD listTitle VARIABLE AS PUBLIC VARIABLE ABOVE WHICH IS GIVEN VALUE AT ONBINDVH
// THIS IS BECAUSE THE VALUE WILL CHANGE IF ITEM IS ADDED OR DELETED
}
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:weightSum="1">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/rounded_corners" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.melnykov.fab.FloatingActionButton
android:id="#+id/fab_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:gravity="bottom|end"
android:onClick="addNote"
android:src="#drawable/fab_ic_add"
fab:fab_colorNormal="#color/colorPrimary"
fab:fab_colorPressed="#color/colorPrimaryDark"
fab:fab_colorRipple="#color/colorPrimaryDark" />
</RelativeLayout>
</FrameLayout>
</LinearLayout>
custom_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/main"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp"
android:text="#string/test"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/main"
android:paddingLeft="8dp">
<TextView
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/test"
android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>
Thank you so much to whoever can help me out. I am pulling my hair out as I type.
EDIT: I have confirmed that it is not my ItemTouchHelper class that's the problem. (Tried running without it being called, problem still occurs.)
Also, it seems that when a dialog is shown and the keyboard brought up, the RecyclerView in the background resolves the problem by itself. After dialog is removed, the problem repeats (i.e. Scrolling puts massive space between items)
change in Recycler view match_parent to wrap_content:
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Also change in item layout xml
Make parent layout height match_parent to wrap_content
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
This happened to me many times!
All you need to do is... make layout_height of row file wrap_content and your problem solved..
android:layout_height="wrap_content"
Happy coding!
Its because you are using match_parent in height of root view of the row item in your vertically oriented listview/recyclerview. When you use that the item expands completely wrt to its parent.
Use wrap_content for height when the recyclerview is vertically oriented and for width when it is horizantally oriented.
Avoid taking the view in item layout with a container like this:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data/>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:listPreferredItemHeight"
android:textAppearance="?android:attr/textAppearanceMedium" />
</android.support.constraint.ConstraintLayout>
</layout>
as in this case match_parent will do its work and the problem will still remain! Rather take it like this:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data/>
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:listPreferredItemHeight"
android:textAppearance="?android:attr/textAppearanceMedium" />
</layout>
[Note: Above code has data binding attached to it, don't use <layout> & <data> tags if not using data binding]
Other than this, if you must use any view group containers, than take a look the height and width attributes in the container, and try change those from match_parent to wrap_content. That should resolve the issue. For more transparency, one can try giving background colours and see through it to identify actual problem.
Just for the record: Since in my case we had to implement some "superfancy UI" with overlapping RecyclerView and blur effect toolbar, I had to get rid of clipToPadding="false" within RecyclerView-xml.
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/height_toolbar"
android:paddingBottom="#dimen/height_bottom_bar_container"
//android:clipToPadding="false" <-- remove this flag!
android:scrollbars="vertical"
/>
paddingTopand paddingBottom worked, but we replaced it with some GapViews(empty views, with height of paddingTop and paddingBottom)
if someone is using | recyclerViewObject.setHasFixedSize(true);
try removing it, It was causing the issue in my case.
You can try setting your Viewgroup holding the recyclerview to wrap content
i have this problem and i just use
android:layout_height="wrap_content"
for parent of every item.

SwipeRefreshLayout Issues When Using emptyView and ListView

I'm using a SwipeRefreshLayout wrapped around a ListView. When the ListView is empty, I've set a TextView to appear. This 'works' fine, but when the ListView is empty and the empty view is showing, the SwipeRefreshLayout doesn't display right. If you drag down, no circle comes down but when you release your finger the circle flashes on the screen and then disappears. If you just touch the screen anywhere, in fact, the SwipeRefreshLayout will appear in the same fashion. The following is how I've defined it in my XML:
<FrameLayout
android:id="#+id/empty_view_requests"
android:layout_width="match_parent"
android:layout_centerInParent="true"
android:layout_below="#+id/appbar"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/appbar"
android:id="#+id/buddy_requests_swipe_layout">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/buddy_requests_listview"
android:layout_gravity="center_horizontal|top"
/>
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:layout_gravity="center_horizontal|center_vertical"
android:id="#+id/norequests_textview"
android:text="No buddy requests."/>
</FrameLayout>
EDIT: Activity Code
swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.buddy_requests_swipe_layout);
swipeRefreshLayout.setColorSchemeResources(R.color.lb_green, R.color.lb_orange, R.color.lb_purple);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
VolleyBuddies.makeGetBuddyRequestsAPICall(BuddyRequestsActivity.this, BuddyRequestsActivity.this);
}
});
FrameLayout noRequestsLayout = (FrameLayout)findViewById(R.id.empty_view_requests);
ListView requestsListView = (ListView)findViewById(R.id.buddy_requests_listview);
requestListAdapter = new BuddyRequestsActivityListAdapter(this, this);
requestsListView.setAdapter(requestListAdapter);
requestsListView.setEmptyView(noRequestsLayout);
How can I fix this?
I am pasting working code of mine.Even I have faced the issues. hope this will works for you.
Initially set the emptyview visibility View.GONE.and then on the API Call response callBacks, if there are no items/statuscode..etc ,setvisibility View.VISIBLE and set it as emptyviewfor listview.
findViewById(R.id.lvemptyview).setVisibility(View.GONE);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
if (Utils.isInternetConnected(getApplicationContext())) {
CallAPICall(lat, lng);
mSwipeRefreshLayout.setRefreshing(false);
} }});
on volley response callback
mSwipeRefreshLayout.setRefreshing(false);
if (statuscode== 200) {
try {
String content = new String(arg2, "UTF-8");
MemberResp memberResp;
Gson gson = new Gson();
Type type = new TypeToken<MemberResp>() {
}.getType();
memberResp = gson.fromJson(content, type);
if (memberResp.Status == 1) {
if (memberResp.bar_lists.size() > 0) {
findViewById(R.id.lvemptyview).setVisibility(View.GONE);
setadapter();
} else {
Adapter.ClearAll();
findViewById(R.id.lvemptyview).setVisibility(View.VISIBLE);
lvList.setEmptyView(findViewById(R.id.lvemptyview));
}
Try placing your TextView inside a ScrollView. I found that the SwipeRefreshLayout requires a scrollable view of some sort
Your code would be
<FrameLayout
android:id="#+id/empty_view_requests"
android:layout_width="match_parent"
android:layout_centerInParent="true"
android:layout_below="#+id/appbar"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/appbar"
android:id="#+id/buddy_requests_swipe_layout">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/buddy_requests_listview"
android:layout_gravity="center_horizontal|top"
/>
</android.support.v4.widget.SwipeRefreshLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:layout_gravity="center_horizontal|center_vertical"
android:id="#+id/norequests_textview"
android:text="No buddy requests."/>
</ScrollView>
</FrameLayout>
Should work right away
You have set your parent framelayout as an empty view of the child(listview). Try removing that line.
Empty layout is text view. Please refer following code. and set adapter after SetEmptyListView.
TextView noRequestsLayout = (TextView)findViewById(R.id.norequests_textview);
ListView requestsListView = (ListView)findViewById(R.id.buddy_requests_listview);
requestListAdapter = new BuddyRequestsActivityListAdapter(this, this);
requestsListView.setEmptyView(noRequestsLayout);
requestsListView.setAdapter(requestListAdapter);

Android - Remove a row from horizontal scrollable listview

I have a list view with two text view and a delete button on the right corner (hidden), each list item is scrollable and delete button appears when I scroll to the left. I was able to get the position in the list onclick of delete button but I am unable to remove that list row.
Layout looks like this.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<HorizontalScrollView
android:layout_width="match_parent"
android:scrollbars="none"
android:layout_height="match_parent"
android:focusable="false" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:orientation="horizontal" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutTeamInvitesListItem"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:onClick="onClickTeamInvitesListText"
android:orientation="vertical" >
<com.headsup.customviews.TextViewPlus
android:id="#+id/textViewListNameTeamInvites"
style="#style/text_view_list_item_style"
android:layout_marginTop="10dp"
android:focusable="false" >
</com.headsup.customviews.TextViewPlus>
<com.headsup.customviews.TextViewPlus
android:id="#+id/textViewListEmailTeamInvites"
style="#style/text_view_list_item_style"
android:layout_marginBottom="10dp"
android:focusable="false" >
</com.headsup.customviews.TextViewPlus>
</LinearLayout>
<Button
android:id="#+id/buttonListViewTeamInvite"
android:layout_width="#dimen/teams_invites_listview_button_width"
android:layout_height="match_parent"
android:background="#FFFF0000"
android:onClick="onClickTeamInvitesListButton"
android:text="#string/delete" >
</Button>
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
Now I have to remove the list row when I click on delete button so I have "onClickTeamInvitesListButton" and function calls the activity class where I am redirecting it to the fragment, so that I could access the list view.
The function in activity looks like this.
public void onClickTeamInvitesListButton(View view) {
fragmentTeamInvites.onClickTeamInvitesListButton(view);
}
Function in fragment is like this.
private static ListView listView;
private static MyListAdapter mListAdapter;
...
...
public void onClickDeleteButton(View view) {
int position = listView.getPositionForView(view);
listView.removeViewAt(position);
mListAdapter.notifyDataSetChanged();
}
Found the answer .. needed to change my list code to this.
public void onClickDeleteButton(View view) {
int position = listView.getPositionForView(view);
listDataModel.remove(position);
mListAdapter.notifyDataSetChanged();
}
The problem is this:
public void onClickDeleteButton(View view) {
int position = listView.getPositionForView(view);
listView.removeViewAt(position);
mListAdapter.notifyDataSetChanged();
}
You are removing the item from the ListView, not from the datasource (the adapter). So, when you call notifyDataSetChanged() the adapter attempts to refresh the data, but since nothing has changed in the data, it displays all rows again.
You should remove the item from your adapter, not from the ListView!

ScrollView inside ViewPager, scrolls to middle automatically

I have a ViewPager that contains several instances of the same fragment, this fragment contains an article. The Article view hierarchy is quite simple, a Title, a Banner image, a subtitle and a body; everything but the title is wrapped in a scrollview.
The problem is, when you swipe to a new page, the fragment is presented with the Views at the top, and then it immediately scrolls to the middle of the container. (As a matter of fact it scrolls to the beginning of the TextView with id: article_content)
I have posted the layout at the bottom of the question.
Now, the ViewPager is set with a simple implementation of a FragmentStatePagerAdapter, here's the code:
class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
Bundle args;
int count;
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
this.count = 8;
}
#Override
public Fragment getItem(int position) {
ArticleFragment mPrimaryFragment = new ArticleFragment();
args = new Bundle();
args.putString(ArticleFragment.KEY_ARTICLE_URL, mCurArticleLink);
mPrimaryFragment.setArguments(args);
return mPrimaryFragment;
}
#Override
public int getCount() {
return count;
}
}
The Fragment itself is pretty simple too. First, I check during onCreate to see if we have the article cached, the I call on onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.apk_article_view, null);
mTitle = (TextView) view.findViewById(R.id.article_title);
mBanner = (ImageView) view.findViewById(R.id.article_banner);
mSubTitle = (TextView) view.findViewById(R.id.article_subtitle);
mContent = (TextView) view.findViewById(R.id.article_content);
if (isArticleCached) {
Constants.logMessage("Article is cached, loading from database");
setApkArticleContent();
}
else {
Constants.logMessage("Article isn't cached, downloading");
HtmlHelper.setApkArticleContent(mContext, mUrl, mTitle, mSubTitle, mContent, mBanner);
setRefreshing(true);
}
return view;
}
It is worth noting that setApkArticleContent is a simple set of Texts, nothing fancy:
private void setApkArticleContent() {
mTitle.setText(Html.fromHtml(mCursor.getString(mCursor.getColumnIndex(DbOpenHelper.TITLE))));
mSubTitle.setText(Html.fromHtml(mCursor.getString(mCursor.getColumnIndex(DbOpenHelper.SUBTITLE))));
mContent.setText(Html.fromHtml(mCursor.getString(mCursor.getColumnIndex(DbOpenHelper.BODY))));
UrlImageViewHelper.setUrlDrawable(mBanner, mCursor.getString(mCursor.getColumnIndex(DbOpenHelper.BANNER)));
}
Also, please know that I did not have a pager before, the fragment was only loaded to an empty activity, and it worked without scrolling to the middle of the scrollview.
I am really not sure what is triggering the scroll, and yes, I know I can programatically set it to scroll back to the top after loading, but then again, that'd be two scroll movements when the fragment is loaded and it would be quite noticeable for the user.
Do you guys have any ideas why it would behave like this? Any ideas on how I can stop that unintentional scroll?
Thanks,
Below is the layout for the ArticleFragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/article_title"
style="#style/headerTextBoldNoUnderline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left|center_vertical"
android:text="" />
<ScrollView
android:layout_height="match_parent"
android:layout_width="match_parent"
>
<LinearLayout
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="match_parent"
>
<ImageView
android:id="#+id/article_banner"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="12dp" />
<TextView
android:id="#+id/article_subtitle"
style="#style/HeaderTextItalicNoUnderline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left|center_vertical" />
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="?android:attr/dividerVertical" />
<TextView
android:id="#+id/article_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:gravity="left|center_vertical"
android:padding="8dp"
android:textColor="?android:attr/textColorSecondary"
android:textIsSelectable="true"
android:textSize="16sp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
This is likely caused by android:textIsSelectable. You may try adding the following to the ScrollView:
android:focusable="true"
android:focusableInTouchMode="true"
android:descendantFocusability="beforeDescendants"
Add this attribute value android:descendantFocusability="blocksDescendants" to the child of ScrollView, according to this question: How to prevent a scrollview from scrolling to a webview after data is loaded?
I also had this problem. I solved it with setting android:focusable="true" and android:focusableInTouchMode="true" to the first element in the ScrollView's LinearLayout.
i try to add
android:focusable="true"
android:focusableInTouchMode="true"
android:descendantFocusability="beforeDescendants"
in the root viewGroup .
it's work's well.
like below.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:descendantFocusability="beforeDescendants"
android:background="#color/normal_bg">
<ScrollView
android:id="#+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/rl_enter"
android:scrollbars="none">
</ScrollView>
</RelativeLayout>
I tried solution:
android:focusable=true
android:focusableInTouchMode=true
android:descendantFocusability=beforeDescendants
And i dont know why but I cant do this with my RelativeLayout which is parent view (this does not work).
I had to wrap my TextView inside FrameLayout and now everything is ok. Maybe this helps somebody.
<FrameLayout
android:id="#+id/detail_description_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/detail_parameters_container"
android:layout_centerInParent="true"
android:descendantFocusability="beforeDescendants"
android:focusable="true"
android:focusableInTouchMode="true" >
<TextView
android:id="#+id/detail_descritpion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="all"
android:padding="10dp"
android:textIsSelectable="true" />
</FrameLayout>
ScrollView inside ViewPager scrolls automatically but does not scrolls in middle..
Check out this.
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
int x=iv.getLeft();
int y=iv.getTop();
scroll.scrollTo(x, y);
}
pager is ViewPager's object and scroll is ScrollView and iv is any View say TextView or ImageView.
When we change page in viewpager, scrollbar automatically scrolls but to the left. If you would have find solution to middle please let me know.. :)

Categories

Resources