i have an activity, which includes a fragment. This fragment includes a Recycler View.
I want it to display data of a game in a grid.
I need it to scroll down (every round of the game is one row) but also horizontal, because i need 5 - 10 Columns.
When id use the paramter android:scrollbars="vertical|horizontal" in the recycler view it only scrolls down and makes it column very small. This happens even when i set it only to horizontal.
How it shouldnt look..
Code:
The Activity
<?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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.sb.matt.doppelkopf.activities.GameActivity">
<fragment
android:id="#+id/fragment_game"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.sb.matt.doppelkopf.fragments.game_fragment"
tools:layout="#layout/fragment_game">
</fragment>
</RelativeLayout>
The Fragment
<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"
tools:context="com.sb.matt.doppelkopf.fragments.game_fragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_gameData"
android:scrollbars="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
The View for the Items in the Recycler View
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="400dp"
android:layout_height="200dp">
<TextView
android:layout_width="400dp"
android:layout_height="200dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Test"
android:id="#+id/txt_inhalt"
android:layout_centerVertical="true"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
</RelativeLayout>
Fragment Code
package com.sb.matt.doppelkopf.fragments;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.sb.matt.doppelkopf.R;
import com.sb.matt.doppelkopf.activities.GameActivity;
import com.sb.matt.doppelkopf.adapters.GameData_Adapter;
import com.sb.matt.doppelkopf.data.GameData;
/**
* A simple {#link Fragment} subclass.
*/
public class game_fragment extends Fragment
{
private GameData gameData;
private RecyclerView rGridView;
GameData_Adapter adapter;
public game_fragment()
{
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the layout for this fragment
final View v = inflater.inflate(R.layout.fragment_game, container, false);
gameData = ((GameActivity)getActivity()).getGameData();
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
String[][] gameData = ((GameActivity) getActivity()).getGameData().getViewData();
rGridView = (RecyclerView) getActivity().findViewById(R.id.recyclerView_gameData);
rGridView.setLayoutManager(new GridLayoutManager(getActivity(), gameData[0].length));
adapter = new GameData_Adapter(gameData);
rGridView.setAdapter(adapter);
}
}
Adapter Code, its uses a 2 dimensional Array to fill the Grid.
package com.sb.matt.doppelkopf.adapters;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.sb.matt.doppelkopf.R;
import com.sb.matt.doppelkopf.data.SingleGameDataItem;
import java.util.ArrayList;
/**
* Created by matts on 16.01.2016.
*/
public class GameData_Adapter extends RecyclerView.Adapter<GameData_Adapter.ViewHolder>
{
private String[][] gameData;
private ArrayList<SingleGameDataItem> list;
public static class ViewHolder extends RecyclerView.ViewHolder
{
View MyView;
TextView textView;
public ViewHolder(View view)
{
super(view);
MyView = view;
textView = (TextView) view.findViewById(R.id.txt_inhalt);
}
}
public GameData_Adapter (String[][] gameData)
{
this.gameData = gameData;
list = new ArrayList<SingleGameDataItem>();
for(int i = 0; i < gameData.length; i++)
{
for(int j = 0; j < gameData[0].length; j++)
{
SingleGameDataItem item = new SingleGameDataItem(gameData[i][j]);
list.add(item);
}
}
}
#Override
public GameData_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.singlegamedataitem, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.textView.setText(list.get(position).getInhalt());
}
#Override
public int getItemCount()
{
return list.size();
}
}
What i am doing wrong? :/
You used wrong constructor new GridLayoutManager(getActivity(), gameData[0].length). Javadoc says that it "Creates a vertical GridLayoutManager".
Try new GridLayoutManager(getActivity(), 1, GridLayoutManager.HORIZONTAL, false)
instead.
Here 1 counts as number of rows.
Related
6 grid should be shown without scrolling, that is it should be like setting layout_weight="1" & layout_height="1" for every grid cards.
6 cards should be shown respective of screen size.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<GridView
android:id="#+id/gvImages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintVertical_weight="1"
app:layout_constraintHorizontal_weight="1"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
grid_layout.xml
<?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"
xmlns:tools="http://schemas.android.com/tools">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
tools:srcCompat="#tools:sample/avatars" />
</LinearLayout>
MyAdapter.java
package com.aijishnu.baseadaptersample;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.aijishnu.baseadaptersample.databinding.GridLayoutBinding;
public class MyAdapter extends BaseAdapter {
Context c;
int items[];
MyAdapter(Context c, int arr[]) {
this.c = c;
items = arr;
}
#Override
public int getCount() {
return items.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
GridLayoutBinding itemBinding = GridLayoutBinding.inflate(LayoutInflater.from(parent.getContext()), parent,false);
holder = new ViewHolder(itemBinding);
holder.view = itemBinding.getRoot();
holder.view.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.binding.imageView.setImageResource(items[position]);
return holder.view;
}
private static class ViewHolder {
private View view;
private GridLayoutBinding binding;
ViewHolder(GridLayoutBinding binding) {
this.view = binding.getRoot();
this.binding = binding;
}
}
}
MainActivity.java
package com.aijishnu.baseadaptersample;
import android.os.Bundle;
import com.aijishnu.baseadaptersample.databinding.ActivityMainBinding;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
int[] itemsarray = new int[] {
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground,
};
MyAdapter adapter = new MyAdapter(this, itemsarray);
binding.gvImages.setAdapter(adapter);
}
}
Above code results as like this, (This is not fit to screen height, also have scrolling option, I want 6 cards should fit to screen size)
I want to have like this(all cards equals according to screen size)
NB: These cards should be randomly generated using BaseAdapter or RecyclerAdapter
You can set the number of rows and columns of your GridLayout inside your xml file
Here is my main_activity.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:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.smartrix.horizontal_listview.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Here is my row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_margin="12dp"
android:layout_width="150dp"
android:layout_height="250dp">
<TextView
android:id="#+id/title"
android:textStyle="bold"
android:textSize="20dp"
android:textAlignment="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.CardView>
Here is my mainActivity.java
package com.smartrix.horizontal_listview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.Adapter mAdapter;
private ArrayList<String> mDataSet;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDataSet = new ArrayList<>();
for (int i = 0; i < 20; i++) {
mDataSet.add("New Title #"+i);
}
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new MainAdapter(mDataSet);
mRecyclerView.setAdapter(mAdapter);
}
}
Here is my mainAdapter.java ::
package com.smartrix.horizontal_listview;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
private ArrayList<String> mDataSet;
public MainAdapter(ArrayList<String> mDataSet){
this.mDataSet = mDataSet;
}
#Override
public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MainAdapter.ViewHolder holder, int position) {
holder.mTitle.setText(mDataSet.get(position));
}
#Override
public int getItemCount() {
return mDataSet.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTitle;
public ViewHolder(View itemView) {
super(itemView);
mTitle = (TextView) itemView.findViewById(R.id.title);
}
}
}
This Code Works Perfectly. Now I want to add this Horizontal ListView in Every ListItem of Vertical ListView. How to do this ??
You would simply add a new Horizontally oriented RecyclerView as an item in your list (and you would add it to your adapter).
It is fine to nest RelativeViews into each other.
In your case, add it to your row.xml layout, then inflate it in your mainAdapter.java class
So i just made this simple fragment that contains a RecycleView. The recycle view has a custom made relative layout with two TextViews and a CheckBox. The problem is that a single list item takes up the whole AVD seceen's space and the listener I set for the list item is not working.
here is a screenshot of the AVD screen (I am using android studio)
And when scrolled
The XML layout code
<?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">
<CheckBox
android:id="#+id/list_item_crime_solved_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="4dp"
/>
<TextView
android:id="#+id/list_item_crime_title_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/list_item_crime_solved_check_box"
android:textStyle="bold"
android:padding="4dp"
tools:text="Crime Title"/>
<TextView
android:id="#+id/list_item_crime_date_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/list_item_crime_solved_check_box"
android:layout_below="#id/list_item_crime_title_text_view"
android:padding="4dp"
tools:text="Crime date"
/>
</RelativeLayout>
The Fragment java code:
package com.bignerdranch.android.criminalintent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class CrimeListFragment extends Fragment
{
private RecyclerView mCrimeRecyclerView;
private CrimeAdabter mCrimeAdabter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_crime_list, container, false);
mCrimeRecyclerView = (RecyclerView) v.findViewById(R.id.crime_recycler_view);
mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return v;
}
private void updateUI()
{
CrimeLab crimeLab = CrimeLab.get(getActivity());
List<Crime> crimes = crimeLab.getCrimes();
mCrimeAdabter = new CrimeAdabter(crimes);
mCrimeRecyclerView.setAdapter(mCrimeAdabter);
}
}
The ViewHolder java code:
private class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
private TextView mTitleTextView;
private TextView mDateTextView;
private CheckBox mCrimeSolvedCheckBox;
private Crime mCrime;
public CrimeHolder(View itemView)
{
super(itemView);
mTitleTextView = (TextView) itemView.findViewById(R.id.list_item_crime_title_text_view);
mDateTextView = (TextView) itemView.findViewById(R.id.list_item_crime_date_text_view);
mCrimeSolvedCheckBox = (CheckBox) itemView.findViewById(R.id.list_item_crime_solved_check_box);
}
public void bindCrime(Crime crime)
{
mCrime = crime;
mTitleTextView.setText(mCrime.getTitle());
mDateTextView.setText(mCrime.getDate().toString());
mCrimeSolvedCheckBox.setChecked(mCrime.isSolved());
}
#Override
public void onClick(View v)
{
Intent i=new Intent(getActivity(),CrimeActivity.class);
startActivity(i);
}
}
And the Adapter java code:
private class CrimeAdabter extends RecyclerView.Adapter<CrimeHolder>
{
private List<Crime> mCrimes;
public CrimeAdabter(List<Crime> crimes)
{
mCrimes = crimes;
}
#Override
public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
LayoutInflater inflater = LayoutInflater.from(getActivity());
View v = inflater.inflate(R.layout.list_item_crime, parent, false);
return new CrimeHolder(v);
}
#Override
public void onBindViewHolder(CrimeHolder holder, int position)
{
Crime crime = mCrimes.get(position);
holder.bindCrime(crime);
}
#Override
public int getItemCount()
{
return mCrimes.size();
}
}
It's because your root RelativeLayout's height is set to match_parent. Make it wrap_content or specific height.
I want to use a spinner in my android fragment. For the purpose, I wrote the following code:
package com.example.shiza.dailyquranverses;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
/**
* A simple {#link Fragment} subclass.
*/
public class completeQuran extends Fragment implements AdapterView.OnItemSelectedListener {
Spinner spinner;
public completeQuran() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_complete_quran, container, false);
spinner = (Spinner)view.findViewById(R.id.selectChapter);
ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity().getApplicationContext(),R.array.chapters,android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
return view;
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
int quran_id;
String chapter_verse="";
TextView textView;
position++;
String chapter_array_name = "chapter_" + position;
quran_id = getResources().getIdentifier(chapter_array_name, "array", getActivity().getApplicationContext().getPackageName());
String[] chapter = getResources().getStringArray(quran_id);
for ( int item = 0 ; item < chapter.length ; item++ )
{
// if ( item > 0 )
// {
// chapter_verse += item + ". " ;
// }
chapter_verse += chapter[item] + "\n";
}
textView = (TextView)view.findViewById(R.id.verse);
textView.setText(chapter_verse);
textView.setMovementMethod(new ScrollingMovementMethod());
}
#Override
public void onNothingSelected(AdapterView<?> parent)
{
Toast.makeText(getActivity().getApplicationContext(),"Please enter your choice",Toast.LENGTH_LONG).show();
}
}
I am getting error at
textView.setText(chapter_verse);
in onItemSelected method. I am using its view to get values from xml. The xml corresponding to the fragment looks like:
<?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">
<Spinner
android:id="#+id/selectChapter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/backgroundColor"
android:orientation="vertical">
<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="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:scrollbars="vertical"
tools:context="com.example.shiza.dailyquranverses.Quran">
<TextView
android:id="#+id/verse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2000"
android:scrollbars="vertical"
android:text="Hello from Quran"
android:textSize="#dimen/verse_font_chapter" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Please help me to solve this.
The onItemSelected callback tells you when a certain item in your Spinner has been selected. The View that exists as a parameter in that callback is the View in the Spinner that was selected. For this reason, I'm guessing that your textView variable will be null. The View that you are trying to access is not enclosed within the View that is being selected, it is enclosed in your layout in general. You should set the reference to that TextView inside of your OnCreateView like so:
public class completeQuran extends Fragment implements AdapterView.OnItemSelectedListener
{
Spinner spinner;
TextView textView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_complete_quran, container, false);
spinner = (Spinner)view.findViewById(R.id.selectChapter);
ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity().getApplicationContext(),R.array.chapters,android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
textView = (TextView)view.findViewById(R.id.verse); //notice the view that this is finding your textview within
return view;
}
}
Then you can use that reference to textView in your onItemSelected callback. You don't need to redefine the reference every time.
It's because setText eat a charSequence and you give a String
you need to use
textView.setText(String.valueOf(chapter_verse))
The issue was with:
textView = (TextView)view.findViewById(R.id.verse);
I need to use getView() method instead of view method.
I've seen a few questions on making a GridView span over multiple "pages" using ViewPager, but what I am trying to do is to have a ViewPager as an item within a GridView.
Here is a simple image attempting to illustrate the UI I'm after: image desired outcome
This shows a 2 item wide grid view (expanding vertically), each item has a title and a view pager with multiple pages with the ability to "swipe" left/right to the next page in a nice animated way.
Below is the code for a very simplified version that shows the issue I am having, I've bypassed some of the normal things you would do when using ArrayAdapters:
MainActivity.java
package com.example.viewpageringridviewtest;
import java.util.ArrayList;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.TextView;
public class MainActivity extends FragmentActivity {
private static final String TAG = "VPinGVTest";
private ArrayList<String> mBoxes = new ArrayList<String>();
private ArrayList<String> mItems = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 1; i <= 1; i++) mBoxes.add("Box " + i);
for (int i = 1; i <= 3; i++) mItems.add("Page " + i);
GridView grid = (GridView) findViewById(R.id.grid);
GridAdapter adapter = new GridAdapter(this, R.layout.grid_item);
grid.setAdapter(adapter);
}
private class GridAdapter extends ArrayAdapter<String> {
private LayoutInflater mLayoutInflater;
public GridAdapter(Context context, int resource) {
super(context, resource);
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mBoxes.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d(TAG, "GridAdapter::getView(" + position + ")");
View v = convertView;
Holder holder = null;
if (v == null) {
Log.d(TAG, "Inflating R.layout.grid_item");
v = mLayoutInflater.inflate(R.layout.grid_item, null);
holder = new Holder(v);
v.setTag(holder);
} else {
Log.d(TAG, "Recycling view");
holder = (Holder) v.getTag();
}
holder.populate(position);
return v;
}
private class Holder {
private View mRow;
private TextView mTitle;
private ViewPager mViewPager;
private ItemPagerAdapter mItemPagerAdapter;
public Holder(View v) {
mRow = v;
mTitle = (TextView) mRow.findViewById(R.id.txt_title);
mViewPager = (ViewPager) mRow.findViewById(R.id.pager);
mItemPagerAdapter = new ItemPagerAdapter(getSupportFragmentManager());
}
public void populate(int position) {
mTitle.setText(mBoxes.get(position));
mViewPager.setAdapter(mItemPagerAdapter);
}
}
}
private class ItemPagerAdapter extends FragmentPagerAdapter {
public ItemPagerAdapter(FragmentManager fm) {
super(fm);
Log.i(TAG, "Creating new ItemPagerAdapter");
}
#Override
public Fragment getItem(int position) {
Log.d(TAG, "Creating fragment for item in position " + position);
return new ItemFragment(mItems.get(position));
}
#Override
public int getCount() {
return mItems.size();
}
}
private class ItemFragment extends Fragment {
private String mItem;
public ItemFragment(String item) {
mItem = item;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "Inflating layout R.layout.grid_item_page");
View view = inflater.inflate(R.layout.grid_item_page, container, false);
((TextView) view.findViewById(R.id.txt_page_title)).setText(mItem);
return view;
}
}
}
activity_main.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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<GridView
android:id="#+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"
android:columnWidth="140dp"
android:stretchMode="columnWidth"
android:animateLayoutChanges="true"
android:verticalSpacing="7dp"
android:horizontalSpacing="7dp" />
</RelativeLayout>
grid_item.xml
<?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"
android:background="#FF0000">
<TextView
android:id="#+id/txt_title"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- View Pager -->
<android.support.v4.view.ViewPager
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_dark" />
</LinearLayout>
grid_item_page.xml
<?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" >
<TextView
android:id="#+id/txt_page_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Here is the image of the output actual outcome. As you can see the View pager is not appearing at all as though it hasn't got any content. Using the code above, here are the log messages that I get:
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Inflating R.layout.grid_item
I/VPinGVTest(2134): Creating new ItemPagerAdapter
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
D/VPinGVTest(2134): Creating fragment for item in position 0
D/VPinGVTest(2134): Creating fragment for item in position 1
D/VPinGVTest(2134): Inflating layout R.layout.grid_item_page
D/VPinGVTest(2134): Inflating layout R.layout.grid_item_page
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Inflating R.layout.grid_item
I/VPinGVTest(2134): Creating new ItemPagerAdapter
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
So it is calling getView(0) many times, the first time of which it creates the pager adapter and eventually create the fragments. Further calls to getView(0) recycle the view except the 4th one which re-inflates the layout, creates the pager adapter but no fragments are created.
Appreciate if any one has any ideas of how to fix this or whether there is a better solution I can use.