SwipeRefreshLayout with RecyclerView not working in Fragment - android

I have a recyclerview inside SwipeRefreshLayout in a fragment. I have implemented AsyncTask to fetch data for recyclerview. The problem is SwipeRefreshLayout does not show at all, and hence the data is not populated in recyclerview. I have done the same thing for Activity and it works just fine but not in fragment. Can anybody guide me what am I doing wrong?
This is the layout file for fragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".FeatureFragment">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
And here is what I've done in the fragment class.
public class FeaturedFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private RecyclerView mRecyclerView;
private SwipeRefreshLayout mSwipeLayout;
public FeaturedFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_featured_captions, container, false);
mRecyclerView = view.findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mSwipeLayout = view.findViewById(R.id.refresh_layout);
mSwipeLayout.setOnRefreshListener(this);
return view;
}
#Override
public void onRefresh() {
new FetchFeedTask().execute((Void) null);
}
private class FetchFeedTask extends AsyncTask<Void, Void, Boolean> {
#Override
protected void onPreExecute() {
mSwipeLayout.setRefreshing(true);
}
#Override
protected Boolean doInBackground(Void... voids) {
//things to do in background
}
#Override
protected void onPostExecute(Boolean success) {
mSwipeLayout.setRefreshing(false);
mRecyclerView.setAdapter(/*adapter*/);
//things to do at the end
}
}
}

It's too late to answer here but might help someone else.
I faced the same issue and it is because the recyclerView is immediate child of swipeRefreshLayout so simply put the recyclerView in a layout (for example ConstraintLayout) and then put this layout in your swipeRefreshLayout and everything will work as you expected.

May your code not working because of ReacyclerView scroll Listener
Try below snipped.
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int topRowVerticalPosition =
(recyclerView == null || recyclerView.getChildCount() == 0) ? 0 : recyclerView.getChildAt(0).getTop();
mSwipeLayout.setEnabled(topRowVerticalPosition >= 0);
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
Also, add your initialization stuff inside onViewCreated() like below
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_featured_captions, container, false);
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView = view.findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mSwipeLayout = view.findViewById(R.id.refresh_layout);
mSwipeLayout.setOnRefreshListener(this);
}

Change the height of swipelayout to wrap_content
Solution 1 :)
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
Solution 2:) Use swipe layout and recycler view using design library
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</android.support.v4.widget.SwipeRefreshLayout>

Use NestedScrollView . put your recycleview or listview inside it. with
android:nestedScrollingEnabled="true"
Complete example -
<androidx.core.widget.NestedScrollView
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:isScrollContainer="false"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
android:clipToPadding="false"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.customfont.MyTextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=" Title"
android:textSize="22dp"
android:textColor="#color/black"/>
<com.customfont.MyTextView
android:id="#+id/title2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=" Title"
android:textSize="22dp"
android:textColor="#color/black"/>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/mSwipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MissingConstraints">
<com.pagenia.app.exoplayer.utils.ExoPlayerRecyclerView
android:id="#+id/exoPlayerRecyclerView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="true"
android:background="#FFFFFF"
android:dividerHeight="8dp" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

Try using the below snippet:
Always use support library widgets. instead of these:
<androidx.recyclerview.widget.RecyclerView
and
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
So:
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>

Related

android recyclerView horizontal and vertical spacing

Hi all I am very new to android and I am having a problem with recyclerview. I am trying to add space between image views in a recyclerview but I am not successful.
What I want
What is happening
Below are my implementations
ItemOffsetDecoration.java
public class ItemOffsetDecoration extends RecyclerView.ItemDecoration {
private int itemOffset;
public ItemOffsetDecoration(int itemOffset) {
itemOffset = itemOffset;
}
public ItemOffsetDecoration(#NonNull Context context, #DimenRes int itemOffsetId) {
this(context.getResources().getDimensionPixelSize(itemOffsetId));
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(itemOffset, itemOffset, itemOffset, itemOffset);
}
}
shopping.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/shopping_bg"
tools:context=".activities.HomepageActivity$PlaceholderFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/shoppingRV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:padding="#dimen/grid_horizontal_spacing"/>
</RelativeLayout>
Shopping.java
public class Shopping extends Fragment implements InstaPukkeiRecyclerViewAdapter.ItemClickListener {
InstaPukkeiRecyclerViewAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab_shopping, container, false);
processRV(rootView);
return rootView;
}
private void processRV(View layout) {
RecyclerView recyclerView = (RecyclerView) layout.findViewById(R.id.shoppingRV);
int noOfColumns = 3;
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), noOfColumns));
adapter = new InstaPukkeiRecyclerViewAdapter(getContext(), LogoIds.SHOPPING_SITE_LOGOS);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
recyclerView.addItemDecoration(new ItemOffsetDecoration(getContext(), R.dimen.grid_horizontal_spacing));
}
}
Please help me here. Thanks in advance.
EDIT
item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/logoImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:marginLeft="18dp"
android:marginRight="18dp"
android:id="#+id/logoImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true" />
</LinearLayout>
Change your item layout with this one in your item's XML. You make the parent(LinearLayout) height match parent that's why you are getting vertical full screen space
Use wrap_content in RecyclerView and also in row layout.And also add margins
<android.support.v7.widget.RecyclerView
android:id="#+id/shoppingRV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:padding="#dimen/grid_horizontal_spacing"/>
hmmm you can add margin to your image view or use dimen to set height and width something like this
android:layout_width="#dimen/dp_130"
android:layout_height="#dimen/dp_120"
or
<ImageView
android:id="#+id/logoImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:layout_margin="#dimen/dp_15"
android:adjustViewBounds="true" />
Inside your Recycleview set layout height to wrap_content

onChildViewDetachedFromWindow not working when recyclerview inside nestedscrollview

I am using LinearLayoutManager with RecyclerView which is inside NestedScrollView. Everything is working fine but addOnChildAttachStateChangeListener not wroking
My xml file of fragmnet is
=====================================================:
<LinearLayout 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/parent_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dedcdc"
android:orientation="vertical">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.NestedScrollView
android:id="#+id/nested_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/layout_rel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#color/app_bg"
android:paddingBottom="#dimen/margin_16dp"
android:paddingLeft="#dimen/margin_10dp"
android:paddingRight="#dimen/margin_10dp"
android:paddingTop="#dimen/margin_16dp">
<ImageView
android:id="#+id/image_user"
android:layout_width="#dimen/post_profile_dp_size"
android:layout_height="#dimen/post_profile_dp_size"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:scaleType="fitXY"
tools:src="#drawable/default_user" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="#dimen/margin_5dp"
android:layout_toLeftOf="#+id/button_add_post"
android:layout_toRightOf="#+id/image_user"
android:gravity="center_vertical"
android:text="Say something" />
</RelativeLayout>
<ProgressBar
android:id="#+id/progress_bar_horizontal"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="10dip"
android:scaleY="2"
android:layout_below="#+id/layout_rel"
android:layout_centerVertical="true"
android:indeterminate="true" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_below="#+id/progress_bar_horizontal"/>
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
and code in myfragmnet is
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mNestedScrollView = (NestedScrollView) view.findViewById(R.id.nested_scrollview);
mNestedScrollView.setNestedScrollingEnabled(false);
mHorizontalProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar_horizontal);
mHorizontalProgressBar.setVisibility(View.GONE);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout);
mSwipeRefreshLayout.setRefreshing(false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
mRecyclerView.setNestedScrollingEnabled(false);
mLinearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
mAdapter = new DataListAdapter(this, getContext(), arrayList);
mRecyclerView.setAdapter(mAdapter);
endlessNestedScrollListener = new EndlessNestedScrollListener(mLinearLayoutManager) {
#Override
public void onLoadMore(int page, int totalItemsCount) {
LoadMoreData();
}
};
mNestedScrollView.setOnScrollChangeListener(endlessNestedScrollListener);
mRecyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(View view) {
}
#Override
public void onChildViewDetachedFromWindow(View view) {
Log.d("tag","on detach");
}
});
}
Method onChildViewDetachedFromWindow in above code is not called because of nrestedscrollview.Is there any solution for it? Without nestedscrollview its woking perfectly, but i need to use nestedscrollview in my code.
onChildViewDetachedFromWindow is not called simply because when you use RecyclerView with WRAP_CONTENT inside NestedScrollView it attaches all elements at once and keeps them all the time. In other words elements will never be detached from RecyclerView inside NestedScrollView

How to save scroll position of recyclerview in fragment

I have followed so many answers from here.. but not a single one solving my issue .. that's why i am asking.
I want to save scroll position in a fragment.
In So many articles they have suggested to follow
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
and
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
But this two method is not available in fragment.
My code:
private int mPositionIng = RecyclerView.NO_POSITION;
private String KEY_POSITION_ING = "KeyPositionIng";
in OnCreateView()
if (savedInstanceState != null) {
if (savedInstanceState.containsKey(KEY_POSITION_ING)) {
mPositionIng = savedInstanceState.getInt(KEY_POSITION_ING);
}
}
Override Methods in fragment They are not same method as above. i don't know where i am doing wrong.
#Override
public void onSaveInstanceState(Bundle outState) {
int scrollPositionIng = mRecyclerViewIngredients.computeVerticalScrollOffset();
mPositionIng = scrollPositionIng;
outState.putInt(KEY_POSITION_ING, mPositionIng);
super.onSaveInstanceState(outState);
}
#Override
public void onViewStateRestored(#Nullable Bundle savedInstanceState) {
if (mPositionIng != RecyclerView.NO_POSITION) {
mRecyclerViewIngredients.getLayoutManager().scrollToPosition(mPositionIng);
}
super.onViewStateRestored(savedInstanceState);
}
I just need to save scroll position while the orientation changes .. Please help.
Any Suggestion will be help full. Thanks......
Update
Everything I wrote below is correct, but the reason it didn't work for you is that I didn't realize how your Activity's layout was structured. Here is your Activity's layout (slightly cleaned up):
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tapan.recipemaster.activity.RecipeDetailActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:id="#+id/fl_fragment_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/padding_10dp"/>
</RelativeLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
Meanwhile, this is your Fragment's layout (again, slightly cleaned up):
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tapan.recipemaster.fragment.RecipeDetailFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/padding_10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorAccent"
android:orientation="vertical">
<TextView
android:id="#+id/tv_ingredient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:textSize="#dimen/text_23sp"
android:text="Ingredients"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_ingredients"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dimen_8dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tv_step"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dimen_8dp"
android:textColor="#color/colorPrimaryDark"
android:textSize="#dimen/text_23sp"
android:text="Steps"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_steps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dimen_8dp"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
</FrameLayout>
Both RecyclerViews have android:layout_height="wrap_content", which means they do not scroll. Rather, the ScrollView in your Activity is the view providing the scrolling behavior, so it is this view whose scroll position must be saved.
You can have the system do this for you by giving this ScrollView an id. Any id you want, as long as it's unique. You don't have to write any Java at all.
<ScrollView
android:id="#+id/thisfixestheproblem"
android:layout_width="match_parent"
android:layout_height="match_parent">
Make sure you're modifying the ScrollView in your activity's layout, not the one in your fragment's layout.
Original
None of the code you posted should be necessary to save your RecyclerView's scroll position on orientation change. As long as the RecyclerView has a unique ID in your layout, it will save the scroll position for you automatically.
Here is a very small sample app that shows automatic saving of scroll position, even with a dynamically added Fragment. As you can see, the only instance state I'm saving myself is whether the button to start the fragment should be visible.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button button;
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("buttonVisible", button.getVisibility() == View.VISIBLE);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content, new MyFragment())
.commit();
button.setVisibility(View.GONE);
}
});
if (savedInstanceState != null) {
boolean buttonVisible = savedInstanceState.getBoolean("buttonVisible");
button.setVisibility(buttonVisible ? View.VISIBLE : View.GONE);
}
}
}
MyFragment.java
public class MyFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.myfragment, container, false);
RecyclerView recycler = (RecyclerView) root.findViewById(R.id.recycler);
recycler.setAdapter(new MyAdapter());
return root;
}
private static class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.itemview, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Drawable d = new ColorDrawable(Color.argb(0xff, 0, 0, position));
ViewCompat.setBackground(holder.image, d);
holder.text.setText("" + position);
}
#Override
public int getItemCount() {
return 256;
}
}
private static class MyViewHolder extends RecyclerView.ViewHolder {
final View image;
final TextView text;
MyViewHolder(View itemView) {
super(itemView);
this.image = itemView.findViewById(R.id.image);
this.text = (TextView) itemView.findViewById(R.id.text);
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="create fragment"/>
</FrameLayout>
myfragment.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:listitem="#layout/itemview"/>
itemview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<View
android:id="#+id/image"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="12dp"
tools:background="#333"/>
<TextView
android:id="#+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:text="text"/>
</LinearLayout>
Let the Android OS handle that for you, in AndroidManifest.xml inside your wanted tag activity add:
android:configChanges="orientation|screenSize"
for future coders
I guess when you came back to your fragment you lost position this is because the values stored in the recycler view of the fragment is lost. If you keep code in start or other methods in fragment their scope is lost.
keep your code in On Create View in fragment because scope will not be lost it will work maximum times if not try by declaring all variables in class not in local method and initialize in oncreateview method. how to get context in on create view?? you can google

Recylerview not visible inside scrollview or nestedScrollview

I want to place a RecylerView inside NestedScrollView as below
activity_service_menu.xml
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="HELLO" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
ServiceMenuActivity.java
public class ServiceMenuTActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_menu_t);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
rv.setHasFixedSize(true);
rv.setAdapter(new RvAdapter());
}
private static class RvAdapter extends RecyclerView.Adapter<RvAdapter.RvHolder> {
#Override
public RvHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View serviceMenuItemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_service_menu, parent, false);
return new RvHolder(serviceMenuItemView);
}
#Override
public void onBindViewHolder(RvHolder holder, int position) {
}
#Override
public int getItemCount() {
return 100;
}
public static class RvHolder extends RecyclerView.ViewHolder {
public RvHolder(View itemView) {
super(itemView);
}
}
}
}
I have put the linearLayout inside scrollView and nestedScrollView.
But the RecyclerView is not visible. If I replace ScrollView with FrameLayout or any other layout, then RecyclerView is visible.
I want to use nestedScrollView and scroll the total layout when recyclerView is scrolled. Unfortunately recyclerView is not even visible.
Follow this sample will get idea where you done mistake.
Main Line is : android:fillViewport="true".
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:theme="#style/ThemeOverlay.AppCompat.Light"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="24dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<com.app.view.CustomRecyclerView
android:id="#+id/recycler_movie_suggestion"
android:layout_width="match_parent"
android:layout_height="170dp"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
when you use two scrollble element inside each other you are in hot water! you have to calculate the Recycler item height and then find the whole recycler height. look at below link, I explain completely this problem.
Use RecyclerView insdie ScrollView with flexible recycler item height
I hope it help you

How to split window with a Viewpager and Fragment?

I want to make something like this:
As you can see, the ViewPager is at top and window is spitted in a Viewpager and a Fragment.
I have tried following:
activity_homescreen.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeScreenActivity" tools:ignore="MergeRootFrame"
>
<android.support.v4.view.ViewPager
android:id="#+id/home_screen_view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<fragment
android:id="#+id/homescreen_fragment"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
class="com.krupalandharsh.touristguideexperiments.HomeScreenFragment" />
</RelativeLayout>
fragment_homescreen.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="login"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="signup"/>
</LinearLayout>
HomeScreenActivity.java:
public class HomeScreenActivity extends Activity{
ViewPager homescreen_viewpager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
homescreen_viewpager = (ViewPager) findViewById(R.id.home_screen_view_pager);
HomeScreenImageAdapter adapter = new HomeScreenImageAdapter(this);
homescreen_viewpager.setAdapter(adapter);
}
}
HomeScreenFragment.java:
public class HomeScreenFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_homescreen, container, false);
return rootView;
}
}
HomeScreenImageAdapter.java
public class HomeScreenImageAdapter extends PagerAdapter {
private Context context;
private int[] HomeScreenImages = new int[] {
android.R.drawable.ic_menu_report_image,
android.R.drawable.ic_btn_speak_now,
android.R.drawable.ic_dialog_dialer,
};
public HomeScreenImageAdapter(Context context)
{
this.context = context;
}
#Override
public int getCount() {
return HomeScreenImages.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view == ((ImageView)object));
}
#Override
public Object instantiateItem (ViewGroup container, int position){
ImageView imageview = new ImageView(context);
imageview.setImageResource(HomeScreenImages[position]);
imageview.setScaleType(ImageView.ScaleType.FIT_CENTER);
((ViewPager)container).addView(imageview);
return imageview;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((ImageView) object);
}
}
But, I can't see m below fragment. Only ViewPager is showing. Is there any idea you have by which we can split screen in Viewpager and Fragment as above?
There may be other issues as well, but to start with, why not just use LinearLayout as the container, with proper equal weighting?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".HomeScreenActivity"
tools:ignore="MergeRootFrame" >
<android.support.v4.view.ViewPager
android:id="#+id/home_screen_view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<fragment
android:id="#+id/homescreen_fragment"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"
class="com.krupalandharsh.touristguideexperiments.HomeScreenFragment" />
</LinearLayout>
I am confused with your xml of the homepage: "activity_homescreen".
You use relative layout for parent layout, but you also add parameter "weight" for both of two child layout, and one of it use 0dp width.
Would you like to use "weight" to allocate the space for your viewPager and fragment?
I add and change some code and show it in the following. I change the parent layout to LinearLayout and add "weightSum".
For The child layout I give 0dp for height, match_parent for width, and weight to allocate the height of them. You can chanage the parameters to fit your design.
I did not try it so I am not sure it will work. You can try it.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeScreenActivity" tools:ignore="MergeRootFrame"
android:weightSum="6"
>
<android.support.v4.view.ViewPager
android:id="#+id/home_screen_view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"/>
<fragment
android:id="#+id/homescreen_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
class="com.krupalandharsh.touristguideexperiments.HomeScreenFragment" />
</LinearLayout>

Categories

Resources