How to save scroll position of recyclerview in fragment - android

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

Related

BUG Some row in recyclerview not clickable inside view pager in tablet

I have a layout with a view pager and consist of 2 fragments with recycler view
The first four-row is clickable, but the other is not clickable, it's happen in tablet mode.
In Phone mode, everything is working fine.
The strange thing is if the data is short(1 letter only), everything is clickable, but the data is long(more than 3 letters) then it's not clickable from row 4. The FAB button is working. I have already tried using physical tablet and emulated tablet.
I am using View Pager 2
Is this a bug? And how to solve this?
Edited, My RecyclerView Adapter code
private List<Craft> craftList;
private RecyclerViewClickListener clickListener;
private Context mContext;
public int selectedItem = -1;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView name ;
public View container;
private RecyclerViewClickListener mListener;
public MyViewHolder(View view, RecyclerViewClickListener listener) {
super(view);
mListener = listener;
name = (TextView) view.findViewById(R.id.name);
container = view.findViewById(R.id.container);
container.setOnClickListener(this);
}
#Override
public void onClick(View v) {
selectedItem = getBindingAdapterPosition();
if(selectedItem!= RecyclerView.NO_POSITION){
mListener.OnButtonClick(v, getBindingAdapterPosition());
notifyDataSetChanged();
}
}
}
public interface RecyclerViewClickListener {
void OnButtonClick(View view, int position);
}
public CraftAdapter(List<Craft> craftList, RecyclerViewClickListener listener) {
this.craftList = craftList;
clickListener = listener;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.craft_item, parent, false);
mContext = parent.getContext();
return new MyViewHolder(itemView,clickListener);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Craft craft = craftList.get(position);
holder.name.setText(craft.getName());
if(mContext.getResources().getBoolean(R.bool.is_tablet)){
if(selectedItem == position){
holder.container.setBackgroundResource(R.color.light_blue);
}
else{
holder.container.setBackgroundResource(R.color.white);
}
}
}
#Override
public int getItemCount() {
return craftList.size();
}
After wasting so much time. I finally found the root cause.
The cause is the layout using LinearLayout with weight. The weight make it not working, I think it's a bug. But I can solve it using constraintlayout
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:background="#color/white"
android:id="#+id/coordinator_layout">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="CraftFragment"
android:id="#+id/list_fragment"
android:layout_weight="2" -->>This is the root cause
android:layout_width="0dp" -->> This is the root cause
android:layout_height="match_parent"
/>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#color/dark_grey2"/>
<FrameLayout
android:id="#+id/detail_fragment"
android:layout_weight="3"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
So I change it to:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:background="#color/white"
android:id="#+id/coordinator_layout">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="CraftFragment"
android:id="#+id/list_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/detail_fragment"
app:layout_constraintHorizontal_weight="2"/>
<FrameLayout
android:id="#+id/detail_fragment"
android:layout_weight="3"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toRightOf="#+id/list_fragment"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_weight="3"/>
<View
android:id="#+id/divider"
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#color/dark_grey2"
app:layout_constraintLeft_toRightOf="#id/list_fragment"
app:layout_constraintRight_toRightOf="#id/list_fragment"/>
</androidx.constraintlayout.widget.ConstraintLayout>

SwipeRefreshLayout with RecyclerView not working in Fragment

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>

Android Fragments OnCreate vs OnCreateView

I have a fragment with OnCreateView and onCreate. In onCreate() I download some icons and set the in ImageView. The first time the program runs it's ok. The icons are downloaded and set but as soon as I switch tabs and come back onCreateView() is called and resets the interface to exactly how is described in the xml file associated.
I was wondering if its possible to stop this thing to happen. Moving the code from onCreate to onCreateView is not what I want since it just keeps downloading the icons again and again.
Fragment
public class LiveGameTab1Fragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View V = inflater.inflate(R.layout.live_game_tab1, container, false);
return V;
}
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
//download an icon from the internet
Bitmap bitmap = BitmapFactory.decodeByteArray(icon.getIcon(), 0, icon.getIcon().length);
Drawable iconDrawable = new BitmapDrawable(getResources(), bitmap);
imgButton.setImageDrawable(iconDrawable);
}
}
FragmentActivity
public class LiveGameStats extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_game_stats);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.liverealtabcontent, new LiveGameTab1Fragment()).commit();
getSupportFragmentManager().beginTransaction().add(R.id.liverealtabcontent2, new LiveGameTab2Fragment()).commit();
getSupportFragmentManager().beginTransaction().add(R.id.liverealtabcontent3, new LiveGameTab3Fragment()).commit();
}
FragmentTabHost mTabHost = (FragmentTabHost) findViewById(R.id.liveGameTabhost);
mTabHost.setup(LiveGameStats.this, getSupportFragmentManager(), android.R.id.tabcontent);
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("You"),
LiveGameTab1Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Your Team"),
LiveGameTab2Fragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("Your Enemies"),
LiveGameTab3Fragment.class, null);
}
}
live_game_tab1.xml
<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=".DeviceFragment">
<ImageButton
android:id="#+id/champBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button_shape_champ"
/>
</LinearLayout>
activity_live_game_stats.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:id="#+id/activity_live_game_stats"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_light"
tools:context="lucian.leagueassistant.activity.LiveGameStats">
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/liveGameTabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal" />
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/liverealtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/liverealtabcontent2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/liverealtabcontent3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
UPDATE
Read the comments for the right answer
Sorry if the code looks out of line I'm answering from my phone
public class LiveGameTab1Fragment extends Fragment {
Bitmap bitmap;
Drawable iconDrawable;
public LiveGameTab1Fragment() {}
public LiveGameTab1Fragment(Context context
//add this if you need something from resources) {
//I don't know what you mean by icon.getIcon()
bitmap = BitmapFactory.decodeByteArray(icon.getIcon(), 0, icon.getIcon().length);
iconDrawable = new BitmapDrawable(context.getResources(), bitmap);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View V = inflater.inflate(R.layout.live_game_tab1, container, false);
return V;
}
#Override //you need the onViewCreated function again I'm on my phone so I might be wrong about the variables inside so make sure to take the right code and the functions inside
public void onViewCreated(View v) {
super.onViewCreated(v);
//code moved to constructor so the image is initialize only ones
ImageButton imgButton = (ImageButton) v.findViewById(R.id.yourButtonId);
imgButton.setImageDrawable(iconDrawable);
}
}

Simple fragement is not working

I am practicing to multi-pane screen using fragment, but it's not working properly. I want two frame in single activity. One should be static and another will dynamic list.
main_biddingwindow.xml
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="200dp"
android:weightSum="1"
android:id="#+id/ag">
<fragment
android:layout_width="163dp"
android:layout_height="match_parent"
android:name="driver.project_detail"
android:id="#+id/fragment"
android:layout_row="0"
android:layout_column="0" />
<fragment
android:layout_width="184dp"
android:layout_height="match_parent"
android:name="driver.bid_list"
android:id="#+id/fragment2"
android:layout_row="0"
android:layout_column="19" />
</GridLayout>`
main.class
public class biddingWindow extends Activity{
protected void OnCreate(Bundle b){
super.onCreate(b);
setContentView(R.layout.main_biddingwindow);
}
}
bidlist.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>
bid_list.java
public class bid_list extends Fragment {
public View onCreateView(LayoutInflater inflater ,ViewGroup container ,Bundle s){
return inflater.inflate(R.layout.bidlist,container, false);
}
}
output screen
Just Create the objects of both the fragments in activity and you can access everything in fragment
public class bid_list extends Fragment {
public ListView listView;
public View onCreateView(LayoutInflater inflater ,ViewGroup container ,Bundle s){
View view = inflater.inflate(R.layout.bidlist,container, false);
listView = (ListView)view.findViewById(R.id.listView);
return view ;
}
}
public class bid_list extends Fragment {
public ListView listView;
public View onCreateView(LayoutInflater inflater ,ViewGroup container ,Bundle s){
View view = inflater.inflate(R.layout.bidlist,container, false);
listView = (ListView)view.findViewById(R.id.listView);
return view ;
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/ag">
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="driver.project_detail"
android:id="#+id/fragment"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:name="driver.bid_list"
android:id="#+id/fragment2"/>
</LinearLayout>
class Main extends Activity
{
protected void OnCreate(Bundle b){
super.onCreate(b);
setContentView(R.layout.main_biddingwindow);
FrameLayout frame1 = (FrameLayout)findViewById(R.id.fragment);
FrameLayout frame2 = (FrameLayout)findViewById(R.id.fragment);
Fragment1 fragment1 = new Fragment1();
Fragment2 fragment2 = new Fragment2();
frame1.removeAllView();
frame1.addView(fragment1)
frame2.removeAllView();
frame2.addView(fragment2)
}
}

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