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.
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
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.
I followed all the steps from various sources for getting listviews to work but my one
doesn't seem to display anything. This list view code(shown below) is activated with a tab fragment manager I won't put that here as to not bog you all down with code as there's a lot here already. It is most likely a problem with the ListFragment itself but I suppose it could be the adapter.
What happens is nothing gets displayed at all just the searchview that I have put in the main xml layout. I can switch freely between tabs with no crashes but just nothing displays in any of my listviews. I have another list which is a friends list(not included in this code snippet) and that uses a generic view holder interface and that one does not work either which suggests the problem is most likely in my ListFragment but I just can't pinpoint it. Any help is appreciated and I hope some can learn something from this, Thank you.
This is my adapter for the settings category list
package codeblox.com.listfragmentexample;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ToggleButton;
import java.util.ArrayList;
import codblox.com.listfragmentexample.R;
public class SettingsAdapter extends ArrayAdapter<Settings.SettingsCategories>
{
private final Activity context;
String[] text;
ArrayList<Settings.SettingsCategories> itemsCopy;
class ViewHolder
{
public TextView txt;
public CheckBox state;
public ImageView settingImg;
public EditText input;
public ToggleButton toggle;
public Button settingInfo; // click it to show what the setting does
}
public SettingsAdapter(Context context, ArrayList<Settings.SettingsCategories> items)
{
super(context, R.layout.settings_category_row, items);
this.context = (Activity) context;
this.itemsCopy = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = new ViewHolder();
int viewType = this.getItemViewType(position);
if(convertView == null)
{
// inflate the GridView item layout
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.settings_category_row, parent, false);
// initialize the view holder
holder = new ViewHolder();
holder.settingImg = (ImageView) convertView.findViewById(R.id.settingCategoryImg);
holder.txt = (TextView) convertView.findViewById(R.id.settingCategoryName);
convertView.setTag(holder);
} else {
// recycle the already inflated view
holder = (ViewHolder) convertView.getTag();
}
// fill data
holder = (ViewHolder) convertView.getTag();
String s = getItem(position).toString();
holder.txt.setText(itemsCopy.get(position).getSettingText());
holder.settingImg.setImageResource(itemsCopy.get(position).getImgResId());
return convertView;
}
}
This is my list fragment
package codeblox.com.listfragmentexample
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import codeblox.com.listfragmentexample.R;
public class Settings extends ListFragment implements View.OnLongClickListener
{
private ListView settingsList;
private ArrayList<SettingsCategories> mItems;
private ArrayAdapter<SettingsCategories> settingsAdapter;
private int numCategories;
String[] CategoryArray = new String[] {"Privacy and Security","Account","Networks","Camera Options","Storage","Accesibility","Features"};
int[] resIds = new int[] {R.drawable.security_settings_icon,R.drawable.account_settings_icon,
R.drawable.network_settings_icon,R.drawable.camera_settings_icon,R.drawable.storage_settings_icon,
R.drawable.accessibility_settings_icon,R.drawable.feature_settings_icon,};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View settingsView = inflater.inflate(R.layout.settings, container, false);
settingsList = (ListView)settingsView.findViewById(android.R.id.list);
// initialize the items list
return settingsView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
// remove the dividers from the ListView of the ListFragment
settingsList = getListView();
settingsList.setDivider(null);
mItems = new ArrayList<SettingsCategories>();
Resources resources = getResources();
for(int c = 0; c < numCategories; c++)
{
mItems.add(new SettingsCategories(CategoryArray[c],resIds[c]));
}
// initialize and set the list adapter
// settingsAdapter = new SettingsAdapter(this.getActivity(), mItems);
setListAdapter(new SettingsAdapter(getActivity(), mItems));
settingsList.setAdapter(settingsAdapter);
}
public Settings()
{
this.numCategories = CategoryArray.length;
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public boolean onLongClick(View v)
{
return false;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id)
{
Object i = l.getItemAtPosition(position);
}
public class SettingsCategories
{
private String settingText;
private int imgResId;
SettingsCategories(String settingText,int imgResId)
{
this.settingText = settingText;
this.imgResId = imgResId;
}
public String getSettingText()
{
return this.settingText;
}
public int getImgResId()
{
return this.imgResId;
}
}
}
and finally these are my xml layouts (the first one is the main view and the second one is the view of a single item in the list
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<SearchView
android:id="#+id/searchFunction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</SearchView>
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ListView>
</RelativeLayout>
this represents an individual item in the list
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="52dp"
android:layout_height="52dp"
android:id="#+id/settingCategoryImg"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="52dp"
android:text=""
android:id="#+id/settingCategoryName"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/settingCategoryImg"
/>
</RelativeLayout>
You are setting null adapter so it is not refreshing.
you are commented initialization part
check in the following method:
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
// remove the dividers from the ListView of the ListFragment
settingsList = getListView();
settingsList.setDivider(null);
mItems = new ArrayList<SettingsCategories>();
Resources resources = getResources();
for(int c = 0; c < numCategories; c++)
{
mItems.add(new SettingsCategories(CategoryArray[c],resIds[c]));
}
// initialize and set the list adapter
// settingsAdapter = new SettingsAdapter(this.getActivity(), mItems);
setListAdapter(new SettingsAdapter(getActivity(), mItems));
settingsList.setAdapter(settingsAdapter);
}
Your are using ListFragement and again inflating layout. that is not a good idea. when you are extending listfragment then inflating the layout is not required and and modify above method like:
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
// remove the dividers from the ListView of the ListFragment
settingsList = getListView();
settingsList.setDivider(null);
mItems = new ArrayList<SettingsCategories>();
Resources resources = getResources();
for(int c = 0; c < numCategories; c++)
{
mItems.add(new SettingsCategories(CategoryArray[c],resIds[c]));
}
// initialize and set the list adapter
settingsAdapter = new SettingsAdapter(this.getActivity(), mItems);
//setListAdapter(new SettingsAdapter(getActivity(), mItems));
settingsList.setAdapter(settingsAdapter);
}
I'm trying to create a ListView that each cell can be shifted as ViewPager.
Similar to Google Gmail app, that can shift emails in order to delete the emails.
It is working BUT showing nothing.
I created a ListView with BaseAdapter.
The Adapter create ViewPager with PagerAdapter that implements FragmentStatePagerAdapter.
The PagerAdapter activate the Fragment that supposed to show the data at the cells in the pagers.
Can you please help?
package com.tegrity.gui;
import java.util.ArrayList;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MyFregment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* simple ListView
*/
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_view1, container, false);
ListView mMyListView = (ListView) view.findViewById(R.id.myList1);
// create the my adapter
MyAdapter mMyAdapter = new MyAdapter(getActivity());
mMyListView.setAdapter(mMyAdapter);
// This is working but without the ListView
// view = inflater.inflate(R.layout.connect_pager_view, null);
// android.support.v4.view.ViewPager myPagerUnit =
// (android.support.v4.view.ViewPager)
// view.findViewById(R.id.connect_pager);
// PagerAdapter pagerAdapter = new MyPagerAdapter(getFragmentManager(),
// 0);
// myPagerUnit.setAdapter(pagerAdapter);
return view;
}
// the data
private static ArrayList<String> mMyList0 = new ArrayList<String>();
/**
* my adapter
*/
public class MyAdapter extends BaseAdapter {
// the data
private ArrayList<String> mMyList = new ArrayList<String>();
private Context mContext;
private LayoutInflater mInflater;
public MyAdapter(Context context) {
mContext = context;
mInflater = LayoutInflater.from(mContext);
mMyList.add("First line");
mMyList.add("Second line");
mMyList.add("Third line");
mMyList0 = mMyList;
}
#Override
public int getCount() {
return mMyList.size();
}
#Override
public Object getItem(int position) {
return mMyList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// optimization
if (convertView == null) {
convertView = mInflater.inflate(R.layout.connect_pager_view,
null);
}
android.support.v4.view.ViewPager myPagerUnit = (android.support.v4.view.ViewPager) convertView
.findViewById(R.id.connect_pager);
PagerAdapter pagerAdapter = new MyPagerAdapter(
getFragmentManager(), position);
myPagerUnit.setAdapter(pagerAdapter);
myPagerUnit
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
((Activity) mContext).invalidateOptionsMenu();
}
});
return convertView;
}
}
/**
* A simple pager adapter
*/
class MyPagerAdapter extends FragmentStatePagerAdapter {
// parameters from the my adapter
private int mPosition;
public MyPagerAdapter(FragmentManager fm, int position) {
super(fm);
mPosition = position;
}
#Override
public Fragment getItem(int pagePosition) {
return MyUnitFragment.create(pagePosition, mPosition);
}
#Override
public int getCount() {
return 2; // pager of 2 cells
}
}
/**
* my basic unit
*/
public static class MyUnitFragment extends Fragment {
public static final String PAGE = "page";
public static final String POSITION = "position";
private int mPageNumber;
// parameter from the my adapter
private int mPosition;
/**
* Factory method for this fragment class. Constructs a new fragment for
* the given page number.
*/
public static MyUnitFragment create(int pageNumber, int position) {
MyUnitFragment fragment = new MyUnitFragment();
Bundle args = new Bundle();
args.putInt(PAGE, pageNumber);
args.putInt(POSITION, position);
fragment.setArguments(args);
return fragment;
}
public MyUnitFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(PAGE);
mPosition = getArguments().getInt(POSITION);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout containing a title and body text.
View convertView = (View) inflater.inflate(R.layout.bookmark_unit,
container, false);
// page parts
String data = mMyList0.get(mPosition);
TextView textView = (TextView) convertView
.findViewById(R.id.bookmarkText1);
switch (mPageNumber) {
case 0: {
textView.setText(data + " at the first page");
break;
}
case 1: {
textView.setText(data + " at the second page");
break;
}
}
return convertView;
}
/**
* Returns the page number represented by this fragment object.
*/
public int getPageNumber() {
return mPageNumber;
}
}
}
XML for the ListView myList1.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#color/white" >
<ListView android:id="#+id/myList1"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:divider="#drawable/course_divider"
android:dividerHeight="2dp"
android:cacheColorHint="#00000000" >
</ListView>
</LinearLayout>
XML for the Pager connect_pager_view.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/connect_pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</android.support.v4.view.ViewPager>
The list unit my_unit.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView android:id="#+id/myText1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#color/black"
android:layout_marginLeft="6dp">
</TextView>
</LinearLayout>
ViewPager in ListView is a bad idea.
You can use this Swipe-to-Dismiss library for deleting https://github.com/romannurik/android-swipetodismiss
You go through following link to implement gmail like delete from list function:
https://github.com/47deg/android-swipelistview
I want to have a list of elements (using a ListView) and each element in list is styled with a relative layout. Currently, the items are being displayed correctly, however, for some reason the listview items dont glow green when they're clicked. Why is this?
I have removed all code to minimals and it still does this.
Activity class
package com.test;
import android.app.Activity;
public class My_ListView extends Activity
{
private ListView_Adapter listViewAdapter;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.my_listview);
// initialise the list-view object
listViewAdapter = new ListView_Adapter(this);
listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(listViewAdapter);
for (int i=0;i<20;i++)
{
listViewAdapter.add("item "+i);
}
}
public void clicked(View v)
{
v.setBackgroundColor(0xFF0000FF);
}
}
The listview item adapter class
package com.test;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class ListView_Adapter extends ArrayAdapter<String>
{
public ListView_Adapter(Context c)
{
super(c, R.layout.my_listview_item);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
StationFinder_ListViewItemHolder holder = null;
if (row == null)
{
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.my_listview_item, parent, false);
holder = new StationFinder_ListViewItemHolder(row);
row.setTag(holder);
}
else
{
holder = (StationFinder_ListViewItemHolder) row.getTag();
}
holder.populateFrom(getItem(position));
return row;
}
static class StationFinder_ListViewItemHolder
{
private TextView destination = null;
StationFinder_ListViewItemHolder(View row)
{
destination = (TextView) row.findViewById(R.id.text1);
}
void populateFrom(String locationDistance)
{
destination.setText(locationDistance);
}
}
}
my_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<ListView android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
my_listview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="clicked"
>
<TextView android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
I think you may have to call invalidate() after setting the background color.
You may want to do this instead by setting the listSelector and possibly drawSelectorOnTop for your ListView. That way the selection/deselection and clicks will be handled in the normal manner.
Edit - also, since you're using a ListView, you probably want to listen for clicks by setting an OnItemClickListener on your ListView.