i am targeting a tablet 3.2 version. i am displaying a listactivity in the left side of the screen and when user clicks on a listitem the details get displayed on the right side of the screen. as i have different details layout for each item clicked i am displaying a fragment on the right side of the screen. i have a requirement to display on a tabbed layout on the detail section. i extended a fragment and in oncreateview inflated an xml with tabhost as root element. but somehow the fragment is not being inflated. for each tab i have a list view to display.below is the code section...the error i get is NullPointerException.
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
public class Projects extends Fragment implements OnTabChangeListener {
private int mCurrentTab;
private TabHost mTabHost;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View tablayout = inflater.inflate(R.layout.projects, null);
mTabHost = (TabHost)tablayout.findViewById(android.R.id.tabhost);
final View v1 = tablayout.findViewById(R.id.webprojects);
final View v2 = tablayout.findViewById(R.id.androidprojects);
final View v3 = tablayout.findViewById(R.id.iphoneprojects);
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("WEB").setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
// TODO Auto-generated method stub
return v1;
}
}));
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("ANDROID").setContent(new TabHost.TabContentFactory() {
#Override
public View createTabContent(String tag) {
// TODO Auto-generated method stub
return v2;
}
}));
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("IPHONE").setContent(new TabHost.TabContentFactory() {
#Override
public View createTabContent(String tag) {
// TODO Auto-generated method stub
return v3;
}
}));
return tablayout;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
setRetainInstance(true);
mTabHost.setOnTabChangedListener(this);
mTabHost.setCurrentTab(mCurrentTab);
}
#Override
public void onTabChanged(String tabId) {
// TODO Auto-generated method stub
FragmentTransaction FrgTra = getFragmentManager().beginTransaction();
if(tabId.equals("WEB"))
{
if(getFragmentManager().findFragmentByTag(tabId) == null)
{
FrgTra.replace(R.id.webprojects, new ProjectsListFragment("WEB"), tabId).commit();
}
}
if(tabId.equals("ANDROID"))
{
if(getFragmentManager().findFragmentByTag(tabId) == null)
{
FrgTra.replace(R.id.androidprojects, new ProjectsListFragment("ANDROID"), tabId).commit();
}
}
if(tabId.equals("IPHONE"))
{
if(getFragmentManager().findFragmentByTag(tabId) == null)
{
FrgTra.replace(R.id.iphoneprojects, new ProjectsListFragment("IPHONE"), tabId).commit();
}
}
}
}
and the xml i am using is :
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" />
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0">
<FrameLayout android:id="#+id/webprojects"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</FrameLayout>
<FrameLayout
android:id="#+id/androidprojects"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</FrameLayout>
<FrameLayout
android:id="#+id/iphoneprojects"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</FrameLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
please help me resolve this issue....
Unsure your content is initialised correctly with the
new TabHost.TabContentFactory()
call.
I've found that populating a Tab requires an activity that might need extras to extract your information eg the cursor id. You might then need to set the text displayed on the tab and an icon or icon selector so that tab selection is more tailored to your user's experience.
Resources _res = app.getResources();
// Create an Intent to launch an Activity for the tab (to be reused)
Intent _intent = new Intent().setClass(this, WEB_TabActivity.class);
_intent.putExtra("whenNeeded", whenNeeded);
// Initialize a TabSpec for each tab and add it to the TabHost
tabHost.addTab(tabHost.newTabSpec("WEB")
.setIndicator(_res.getString(R.string.WEB_Displayed_Tab_Text),
_res.getDrawable(R.drawable.WEB_icon_selector))
.setContent(_intent));
Example selector is:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- When selected, use color-->
<item android:drawable="#drawable/WEB_ICON_color"
android:state_selected="true" />
<!-- When not selected, use grey -->
<item android:drawable="#drawable/WEB_ICON_Grey" />
</selector>
you then code WEB_TabActivity as any Activity class that would display your desired data.
** CURSOR ADAPTER AND VIEW HOLDER PATTERN
/**
* Adapter that allows us to match product items to layout fragment<p/>
*
* #author The Solar Sheriff
*/
public class MyItemListAdapter extends CursorAdapter {
public final static String TAG = "MyItemListAdapter";
/**
* Constructor from a list of items
*/
private LayoutInflater _li;
private Context _context;
private Cursor _in;
private int _productName,
_count;
public OrderItemListAdapter(Context _Context, Cursor _In) {
super(_Context, _In, true);
_context = _Context;
_li = LayoutInflater.from(_context);
_in = _In;
_productName = _in.getColumnIndex("product_name");
_count = _in.getCount();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public int getCount() {
return _in.getCount();
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View _view = _li.inflate(R.layout.list_item_layout, null);
return _view;
}
private ViewHolder mapItemViewHolder(View _v){
ViewHolder _itemHolder = new ViewHolder();
//Map the views to the ViewHolder
_itemHolder.productName = (TextView) _v.findViewById(R.id.itemProductName);
return _itemHolder;
}
#Override
public void bindView(View _cView, final Context _context, final Cursor _c) {
ViewHolder _itemHolder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (_cView == null) {
_cView = _li.inflate(R.layout.list_item_layout, null);
_itemHolder = mapItemViewHolder(_cView);
_cView.setTag(_itemHolder);
}
else {
// Get the ViewHolder back to get fast access
// Can also get a view with no tag so check for null
if ((_itemHolder = (ViewHolder) _cView.getTag()) == null) {
_itemHolder = mapItemViewHolder(_cView);
_cView.setTag(_itemHolder);
}
}
//*** TEXT VIEWS ***
// Bind the data using the holder.
_itemHolder.productName.setText(_c.getString(_productName));
for(String _display : TabLayouts ) {
if ( _display.equals("WEB") ) _itemHolder.productName.setTag(Integer.toString(R.layout.WEB_layout));
if ( _display.equals("IPHONE") ) _itemHolder.productName.setTag(Integer.toString(R.layout.IPHONE_layout));
if ( _display.equals("ANDROID") ) _itemHolder.productName.setTag(Integer.toString(R.layout.ANDROID_layout));
}
}
static String TabLayouts = { "WEB","IPHONE","ANDROID"};
static class ViewHolder
{
TextView productName;
}
}
// YOUR onSelectedItem LISTENER DOES
MyList.setOnItemSelectedListener( new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> _item, View _View, int _selection, long _id) {
ViewGroup _parent = (ViewGroup)_item.getParent();
TextView _productName = (TextView)_parent.findViewById(R.id.itemProductName);
int _showLayout = Integer.valueOf(_productName.getTag());
//*** e.g. Inflate your fragment layout ***
}
});
Hope this gives you a successful path to follow :)
Related
My Problem:
I have 70 images, and on each image I want to put transparent button
in such a way that when user taps on it, it plays a short audio
regarding the spot on image. Images are displaying in a ViewPager.
My Solution:
Now what I have in mind is I can create 70 fragments each containing respective image as background and I can assign button on each spot easily and assign actions to those buttons which will play their respective audio.
But
this doesn’t look like a good approach to include 70 fragments in a single app.
So how can I achieve this, and what would be a better approach I can use?
We can just have one fragment and create an ArrayList of Map(Button, RelatedAudioFile) data structure for holding buttons and related audio files. ArrayList index represents the page number.
Example:
Now lets say we have 3 viewPages. As most of the PagerAdapter index start from "0", let say Page-0 contains 3 buttons, Page-1 contains 1 button, Page-2 contains 2 buttons.
Pseudocode:
class PagerHolder extends Fragment {
//buttons list - here, arrayList index represents page number
//and at each index we have map of buttons (buttons in each of these pages) and the related audio files
private ArrayList<Map<Button, RelatedAudioFile>> pageButtonsList = new ArrayList<>();
//pager view
private ViewPager viewPager;
//pager adapter
private PagerAdapter pagerAdapter;
//current page number -- page in which we are in right now
private int currentpageNumber = 0;
//buttonListener -- one button listener for all the buttons in all the pages.
private View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View buttonView) {
//here you can play the audio.
//buttonView -- is the same button-object that was pressed.
((RelatedAudioFile)pageButtonsList.get(currentpageNumber).get(buttonView)).play();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pagerAdapter = new PagerAdapter(getChildFragmentManager());
//add buttons to the list
//page 0 buttons
HashMap<Button, RelatedAudioFile> page0Buttons = new HashMap<>();
page0Buttons.put(new Button(context), new RelatedAudioFile());
page0Buttons.put(new Button(context), new RelatedAudioFile());
page0Buttons.put(new Button(context), new RelatedAudioFile());
pageButtonsList.add(page0Buttons)
//Adding page 1 buttons:
HashMap<Button, RelatedAudioFile> page1Buttons = new HashMap<>();
page1Buttons.put(new Button(context), new RelatedAudioFile());
pageButtonsList.add(page1Buttons);
//Adding page 2 buttons:
HashMap<Button, RelatedAudioFile> page2Buttons = new HashMap<>();
page2Buttons.put(new Button(context), new RelatedAudioFile());
page2Buttons.put(new Button(context), new RelatedAudioFile());
pageButtonsList.add(page2Buttons);
for(Map<Button, RelatedAudioFile> pageButtons :pageButtonsList) {
for(Button button : pageButtons.keySet()) {
button.setOnClickListener(listener);
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_editor_pager, container, false);
viewPager = (ViewPager) v.findViewById(R.id.view_pager);
viewPager.setAdapter(pagerAdapter);
return v;
}
private class PagerAdapter extends FragmentPagerAdapter {
private ButtonFragment buttonFragment;
private PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pageNumber) {
currentpageNumber = pageNumber;
//pass the buttons to the fragment so that it can add these buttons to the screen
buttonFragment = ButtonFragment.newInstance(pageButtonsList.get(pageNumber).keySet());
//to add buttons on screen programatically at certain position you can refer here:
// http://stackoverflow.com/questions/3441475/android-change-absolute-position-of-a-view-programmatically
}
//number of pages
#Override
public int getCount() {
return 70;
}
}
You dont have to create 70 fragments. Instead, you could just use one ImageView as follows:
final List<Integer> list = new ArrayList<>();
list.add(R.drawable.img_0);
list.add(R.drawable.img_1);
...
list.add(R.drawable.img_69);
ImageView img = (ImageView)findViewById(R.id.imageView);
img.setBackgroundResource(list.get(yourIndex));
img.setOnClickListener(new OnClickListener());//plays the audio
You don't need to declare 70 fragments, just create one fragment and on that fragment declare global arrays of images and sound. Now when you redirect here at fragment just pass one integer variable in argument. So now you can display the image from array using that integer variable and on button click you can play audio from sound array using same integer number.
Use this custom view pager
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* Created by Jinesh on 06-01-2016.
*/
public class CustomViewPager extends ViewPager {
private boolean enabled;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.enabled = true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onTouchEvent(event);
}
return false;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
/*
if (this.enabled) {
return super.onInterceptTouchEvent(event);
}
*/
return false;
}
public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
}
Add this tag to your xml
<Your_package_name.CustomViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/vP_asq_Pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
Then extend PagerAdapter
public class HomeAdapter extends PagerAdapter {
public HomeAdapter(){
}
#Override
public int getCount() {
return mItemList.size();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = (LayoutInflater) container.getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.adapter_surveyquestion_view, null);
/*do your operations on your views here
store the 70 images in arraylist and return the size of the arraylist in getCount() method of the adapter.show different images each time in
getView based on the position variable.*/
(container).addView(v);
return v;
}
#Override
public boolean isViewFromObject (View view, Object object){
return view == ((View) object);
}
#Override
public void restoreState (Parcelable arg0, ClassLoader arg1){
}
#Override
public Parcelable saveState () {
return null;
}
#Override
public void destroyItem (ViewGroup container,int position, Object object){
container.removeView((View) object);
}
}
This is how I would do. Pleas note that this is a single class solution for example purpose, you can separate classes
This will keep only 5 fragments at a time
Screen is divided into 4 buttons you can set alpha value of buttons and size as per need currently i kept it half transparent for example
I am using Glide for image loading to avoid OOM problem because of image loading
What it look like
The Solution :-
package com.example.sample;
import java.util.ArrayList;
import com.bumptech.glide.Glide;
import android.content.Context;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
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.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class MainActivity extends FragmentActivity {
private static ArrayList<Integer> imageList = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Load image data
for (int i = 0; i < 70; i++) {
imageList.add(R.drawable.ic_launcher);
}
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
ViewPager viewPager = (ViewPager) rootView
.findViewById(R.id.image_pager);
// Limit number of pages that should be retained to either
// side of the current page
viewPager.setOffscreenPageLimit(2);
viewPager.setAdapter(new SongDetailAdapter(getActivity()));
return rootView;
}
}
public static class SongDetailAdapter extends PagerAdapter {
Context mContext;
LayoutInflater mLayoutInflater;
public SongDetailAdapter(Context context) {
mContext = context;
mLayoutInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return imageList.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((FrameLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
View itemView = mLayoutInflater.inflate(
R.layout.image_place_holder, container, false);
ImageView imageView = (ImageView) itemView
.findViewById(R.id.background);
itemView.findViewById(R.id.button1).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
playSound(1);
}
});
itemView.findViewById(R.id.button2).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
playSound(2);
}
});
itemView.findViewById(R.id.button3).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
playSound(3);
}
});
itemView.findViewById(R.id.button4).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
playSound(4);
}
});
Glide.with(mContext).load("").placeholder(imageList.get(position))
.crossFade(300).into(imageView);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((FrameLayout) object);
}
#Override
public Object instantiateItem(View arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
#Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
/*
* Play sound
*/
private void playSound(int buttonNumber) {
switch (buttonNumber) {
case 1: // play sound for Button1
case 2: // play sound for Button2
case 3: // play sound for Button3
case 4: // play sound for Button4
default: // play sound for Button n
// Playing default notification here for example
Uri notification = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager
.getRingtone(mContext, notification);
r.play();
break;
}
}
}
}
Layouts
Main Activity layout activity_main.xml
<FrameLayout 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="com.example.sample.MainActivity"
tools:ignore="MergeRootFrame" />
Main fragment layout fragment_main.xml
<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.example.sample.MainActivity$PlaceholderFragment" >
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/image_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Image place holder with dummy buttons imae_place_holder.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:orientation="horizontal" >
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:alpha=".5"
android:background="#android:color/white"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:alpha=".5"
android:background="#android:color/holo_green_light"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:orientation="horizontal" >
<Button
android:id="#+id/button3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:alpha=".5"
android:background="#android:color/holo_blue_light"
android:text="Button" />
<Button
android:id="#+id/button4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:alpha=".5"
android:background="#android:color/holo_red_light"
android:text="Button" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
I am new to Android and am trying a sample application for showing ViewPagers in a Master-Detail Flow using custom PagerAdapters and FragmentStatePagerAdapters. My application has a list of dummy items managed by a SQLiteDatabase which contain a title String, a description String, a Boolean like status, and a list of images (I plan to implement them as downloading from String urls but presently I'm just trying with a single image resource). I am having two problems in the Detail View.
My intention is to use a ViewPager with a FragmentStatePagerAdapter to show the detail view, which consists of a ViewPager with a custom PagerAdapter for showing the list of images, TextView for title and description, a ToggleButton for the like status and a delete button for deleting items from the list.
Issues:
The ViewPager with the custom PagerAdapter does not display the image. It occupies the expected space and swipes performed on it also behave as expected. Only the image is not visible.
[RESOLVED] On using the delete button, I am able to delete the item from the database, and also update the Master View accordingly, but I am not able to update the Detail View, and the app crashes.
Here is my code:
Code that calls ItemDetailActivity.java
#Override
public void onClick(View v) {
Intent detailIntent = new Intent(getContext(), ItemDetailActivity.class);
detailIntent.putExtra(ItemDetailFragment.ARG_LIST_POSITION, holder.position);
getContext().startActivity(detailIntent);
}
ItemDetailActivity.java
public class ItemDetailActivity extends FragmentActivity {
static ItemDetailPagerAdapter idpa;
static ViewPager detailPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_detail);
idpa = new ItemDetailPagerAdapter(getSupportFragmentManager());
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
detailPager = (ViewPager) findViewById(R.id.item_detail_container);
detailPager.setAdapter(idpa);
detailPager.setCurrentItem(getIntent().getIntExtra(ItemDetailFragment.ARG_LIST_POSITION, 0));
}
}
activity_item_detail.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/item_detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.trial.piclist.ItemDetailActivity"
tools:ignore="MergeRootFrame" />
ItemDetailFragment.java
public class ItemDetailFragment extends Fragment {
public static final String ARG_ITEM_ID = "item_id";
public static final String ARG_LIST_POSITION = "list_index";
public static final String ARG_TWO_PANE = "is_two_pane";
int position = -1;
long id = -1;
boolean twoPane = false;
ViewPager pager;
private PicItem mItem;
public ItemDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
twoPane = getArguments().getBoolean(ARG_TWO_PANE, false);
position = getArguments().getInt(ARG_LIST_POSITION, -1);
id = getArguments().getLong(ARG_ITEM_ID, -1);
if (id == -1)
id = ItemListFragment.getIdByPosition(position);
setmItem(id);
}
public void setmItem(long id) {
if (id >= 0) {
try {
ItemListActivity.lds.open();
mItem = ItemListActivity.lds.getById(id);
ItemListActivity.lds.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
if (mItem != null) {
List<String> pics = new ArrayList<String>();
pics.add("1");
pics.add("2");
pics.add("3");
pics.add("4");
pics.add("5");
mItem.setPics(pics);
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail,
container, false);
DetailViewHolder holder = new DetailViewHolder();
pager = (ViewPager) rootView.findViewById(R.id.pager);
ImagePagerAdapter adapter = new ImagePagerAdapter(mItem, getActivity(),
inflater, position);
pager.setAdapter(adapter);
holder.position = getArguments().getInt(ARG_LIST_POSITION);
holder.ttv = (TextView) rootView.findViewById(R.id.item_title);
holder.dtv = (TextView) rootView.findViewById(R.id.item_detail);
holder.likeButton = (ToggleButton) rootView
.findViewById(R.id.item_like);
holder.deleteButton = (Button) rootView.findViewById(R.id.item_delete);
rootView.setTag(holder);
if (mItem != null) {
holder.ttv.setText(mItem.getTitle());
holder.dtv.setText(mItem.getDescription());
holder.likeButton.setChecked(mItem.getIsLiked());
holder.likeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ItemListActivity.lds.open();
ItemListActivity.lds.toggleLike(mItem.getId());
mItem.toggleIsLiked();
ItemListActivity.lds.close();
ItemListFragment.listDisplayHelper.toggleLiked(position);
}
});
holder.deleteButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ItemListActivity.lds.open();
ItemListActivity.lds.removeItem(mItem.getId());
ItemListActivity.lds.close();
ItemListFragment.listDisplayHelper.remove(position);
ItemListActivity.idpa.notifyDataSetChanged();
// What do I do so that the FragmentStatePagerAdapter is
// updated and the viewpager shows the next item.
}
});
}
return rootView;
}
static private class DetailViewHolder {
TextView ttv;
TextView dtv;
ToggleButton likeButton;
Button deleteButton;
int position;
}
}
fragment_item_detail.xml
<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:orientation="vertical"
android:padding="16dp"
tools:context="com.trial.piclist.ItemDetailFragment" >
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="200dip">
</android.support.v4.view.ViewPager>
<TableRow
android:id="#+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/item_title"
style="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello"
android:textIsSelectable="true" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<include
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="#layout/controls_layout" />
</TableRow>
<ScrollView
android:id="#+id/descScrollView"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/item_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello" />
</LinearLayout>
</ScrollView>
</LinearLayout>
controls_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"
android:orientation="horizontal" >
<ToggleButton
android:id="#+id/item_like"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_gravity="right"
android:background="#android:drawable/btn_star"
android:gravity="center"
android:text="#string/like_list_item"
android:textOff="#string/empty_text"
android:textOn="#string/empty_text" />
<Button
android:id="#+id/item_delete"
style="?android:attr/buttonStyleSmall"
android:layout_width="30dip"
android:layout_height="30dip"
android:background="#android:drawable/ic_menu_delete"
android:text="#string/empty_text" />
</LinearLayout>
Custom PagerAdapter
ImagePagerAdapter.java
public class ImagePagerAdapter extends PagerAdapter {
LayoutInflater inflater;
List<View> layouts = new ArrayList<>(5);
// Constructors.
#Override
public Object instantiateItem(ViewGroup container, int position) {
if (layouts.get(position) != null) {
return layouts.get(position);
}
View layout = inflater.inflate(R.layout.detail_image,
((ViewPager) container), true);
try {
ImageView loadSpace = (ImageView) layout
.findViewById(R.id.detail_image_view);
loadSpace.setBackgroundColor(0x000000);
loadSpace.setImageResource(R.drawable.light_grey_background);
loadSpace.setAdjustViewBounds(true);
} catch (Exception e) {
System.out.println(e.getMessage());
}
layout.setTag(images.get(position));
layouts.set(position, layout);
return layout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
#Override
public int getCount() {
return 5;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (((View) object).findViewById((view.getId())) != null);
}
}
FragmentPagerAdapter
ItemDetailPagerAdapter.java
public class ItemDetailPagerAdapter extends FragmentStatePagerAdapter {
public ItemDetailPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new ItemDetailFragment();
Bundle args = new Bundle();
args.putLong(ItemDetailFragment.ARG_ITEM_ID, ItemListFragment.getIdByPosition(position));
args.putInt(ItemDetailFragment.ARG_LIST_POSITION, position);
args.putBoolean(ItemDetailFragment.ARG_TWO_PANE, ItemListActivity.mTwoPane);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
openDatabase();
int c = database.getCount();
closeDatabase();
return c;
}
#Override
public int getItemPosition(Object object) {
long mId = ((ItemDetailFragment) object).getmId();
int pos = POSITION_NONE;
openDatabase();
if (database.contains(mId)) {
pos = database.getPositionById(mId);
}
closeDatabase();
return pos;
}
}
Any help is much appreciated. Thanks :)
In your ItemDetailFragment, remove the viewpager from the holder, it should be directly into the returned view, something like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail,
container, false);
pager = (ViewPager) rootView.findViewById(R.id.pager);
ImagePagerAdapter adapter = new ImagePagerAdapter(mItem, getActivity(),inflater, position);
pager.setAdapter(adapter);
return rootView;
}
and the ViewHolder pattern should be applied inside your PagerAdapter.
In ImagePagerAdapter.java, correct the isViewFromObject method -
#Override
public boolean isViewFromObject(View view, Object object) {
return (view == (View) object);
}
This will correct the issue of the ImageView.
In ItemDetailPagerAdapter.java, override the getItemPosition method -
#Override
public int getItemPosition(Object object) {
int ret = POSITION_NONE;
long id = ((ItemDetailFragment) object).getId();
openDatabase();
if (databaseContains(id)) {
ret = positionInDatabase(id);
}
closeDatabase();
return ret;
}
On deleting call the FragmentStatePagerAdapter.NotifyDataSetChanged() method. This will make the Adapter update itself on deleting.
Although, the FragmentStatePagerAdapter uses a list of Fragments and of stored states to implement the adapter. That is also causing trouble. To remove that, implement your own list of Fragments.
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 am trying to create a master/detail flow application on Android 4.2.
I have created a master detail flow project, but I want to implement an ExpandableListView instead of the ListView that is provided.
The master/detail uses fragments, and here’s where I am stuck… I have successfully created an expandable list view in a separate project. How can I implement it inside a master/detail flow?
I assume you used the IDE wizard to create the Master/Detail example project. If this is so, then you probably saw that the wizard created an ItemListFragment class which by default extends ListFragment.
If you need to replace the simple list with an expandable one, then you'll have to:
Extend from Fragment, instead of ListFragment
Create an xml layout file where you declare an ExpandableListView
Override onCreateView() and inflate the layout that contains the ExpandableListView
Get a reference to the ExpandableListView, and then use it as you did before.
Something like this:
// extend from Fragment
public class ItemListFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// inflate the layout that contains the ExpandableListView
View view = inflater.inflate(R.layout.fragment_items_list, container, false);
// get a reference to ExpandableListView
ExpandableListView list = (ExpandableListView)view.findViewById(R.id.my_list);
// set the adapter
// set listeners
return view;
}
}
I have no idea how to create ExpandableListView, but you can achieve with custom listview like I implemented in my Project
1. Create Custom list row
<?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:background="#00000000" >
<RelativeLayout
android:id="#+id/rel_main"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginRight="18dp"
android:layout_marginTop="17dp"
android:layout_toLeftOf="#+id/imageView1"
android:paddingBottom="15dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#685f56" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/text1"
android:layout_marginRight="16dp"
android:layout_marginTop="5dp"
android:src="#drawable/highlight_icon" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:layout_alignParentLeft="true"
android:layout_below="#+id/rel_main"
android:visibility="gone" >
</RelativeLayout>
<View
android:id="#+id/view1"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_alignParentLeft="true"
android:layout_below="#+id/relativeLayout1"
android:background="#685f56" />
</RelativeLayout>
**2. Create Custom Adapter in "ItemListFragment.java" **
public class CustomAdepeterNewJob extends BaseAdapter{
//String[] tablecontent;
int Click=0;
Map<String, DummyItem> tablecontent = new HashMap<String, DummyItem>();
Context context;
public CustomAdepeterNewJob(Context context, Map<String, DummyItem> titles)
{
this.context = context;
this.tablecontent = titles;
}
public class ViewHolder {
public TextView txt;
public ImageView img;
public RelativeLayout relativeLayout1,rel_main;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return tablecontent.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
final ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
view = inflater.inflate(R.layout.c_simple_list_item, parent, false);
holder = new ViewHolder();
holder.txt = (TextView) view.findViewById(R.id.text1);
holder.img = (ImageView) view.findViewById(R.id.imageView1);
holder.rel_main=(RelativeLayout) view.findViewById(R.id.rel_main);
holder.relativeLayout1=(RelativeLayout) view.findViewById(R.id.relativeLayout1);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
String s=DummyContent.ITEMS.get(position).content;
System.out.println("==dummy "+s);
holder.txt.setText(s);
if (s.equalsIgnoreCase("All"))
{
holder.img.setImageResource(R.drawable.all_icon);
}else if (s.equalsIgnoreCase("Note")) {
holder.img.setImageResource(R.drawable.notes_icon);
}else if (s.equalsIgnoreCase("Highlight")) {
holder.img.setImageResource(R.drawable.highlight_icon);
}else if (s.equalsIgnoreCase("Snapshots")) {
holder.img.setImageResource(R.drawable.snapshot_icon);
}else if (s.equalsIgnoreCase("Draw")) {
holder.img.setImageResource(R.drawable.draw_icon);
}else if (s.equalsIgnoreCase("Record Sounde")) {
holder.img.setImageResource(R.drawable.sound_recorder_icon);
}
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
if (holder.relativeLayout1.getVisibility()==View.GONE)
{
holder.rel_main.setBackgroundResource(R.drawable.list_item_bg_pressed);
holder.relativeLayout1.setVisibility(View.VISIBLE);
}else {
holder.relativeLayout1.setVisibility(View.GONE);
holder.rel_main.setBackgroundColor(Color.TRANSPARENT);
}
}
});
return view;
}
}
3. And ad Custom Adapter in "onCreate" in ItemListFregment
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO: replace with a real list adapter.
/*setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(getActivity(),
R.layout.c_simple_list_item, R.id.text1, DummyContent.ITEMS));*/
setListAdapter(new CustomAdepeterNewJob(getActivity(), DummyContent.ITEM_MAP));
}
I am currently working on a tabbed layout using fragments for an application for Android >= 4.0. The tabs are not in the action bar. I don't need a new activity for every tab. I always show the same amount and same kind of data.
Since there is no "best practice" guide for my purposes (I think?!) I post my code here (which is working). I hope you find some passages where I can do some (performance) improvements and where I did something that is not "best practice" (e.g. architecture). I already think about the passage where I use the Gridview in the fragment class.
The activity which should show the tabbed layout
public class LevelActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_level);
}
}
The xml file for the above activity
<fragment
class="com.test.puzzle.tabs.TabsFragment"
android:id="#+id/tabs_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
My fragment class:
public class TabsFragment extends Fragment implements OnTabChangeListener {
public static final String TAB_1 = "Pack 1";
public static final String TAB_2 = "Pack 2";
private View mRoot;
private TabHost mTabHost;
private int mCurrentTab;
private TabFragmentAdapter mAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRoot = inflater.inflate(R.layout.tabs_fragment, container, false);
mTabHost = (TabHost) mRoot.findViewById(android.R.id.tabhost);
setupTabs();
return mRoot;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
mTabHost.setOnTabChangedListener(this);
mTabHost.setCurrentTab(mCurrentTab);
updateTab(R.id.tab_1);
}
private void setupTabs() {
mTabHost.setup(); // you must call this before adding your tabs!
mTabHost.addTab(newTab(TAB_1, R.id.tab_1));
mTabHost.addTab(newTab(TAB_2, R.id.tab_2));
}
private TabSpec newTab(String tag, int tabContentId) {
TabSpec spec = mTabHost.newTabSpec(tag);
spec.setContent(tabContentId);
spec.setIndicator(tag);
return spec;
}
#Override
public void onTabChanged(String tabId) {
if (TAB_1.equals(tabId)) {
updateTab(R.id.tab_1);
mCurrentTab = 0;
}
if (TAB_2.equals(tabId)) {
updateTab(R.id.tab_2);
mCurrentTab = 1;
}
}
private void updateTab(int viewId) {
final GridView grid = (GridView) mRoot.findViewById(viewId);
if (mAdapter == null) {
mAdapter = new TabFragmentAdapter(mRoot.getContext(), mTabHost.getCurrentTabTag());
}
grid.setAdapter(mAdapter);
}
}
My xml layout file for the fragment:
<?xml version="1.0" encoding="utf-8"?>
<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="#+id/tab_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"
android:verticalSpacing="20dp"
android:horizontalSpacing="20dp">
</GridView>
<GridView
android:id="#+id/tab_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"
android:verticalSpacing="20dp"
android:horizontalSpacing="20dp">
</GridView>
</FrameLayout>
</LinearLayout>
</TabHost>
My adapter class for the fragements data
public class TabFragmentAdapter extends BaseAdapter {
private Context mContext;
private String mPackString;
private final String[] WORDS = {"test3", "test6", "test4", "test4",
"test1", "test2", "test7", "test3", "test9", "test6",
"test3", "test7"};
public TabFragmentAdapter(Context context, String packString) {
mContext = context;
mPackString = packString;
}
#Override
public int getCount() {
return WORDS.length;
}
#Override
public Object getItem(int i) {
return WORDS[i];
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder viewHolder;
if (view == null) { // if it's not recycled, initialize some attributes
final LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_item, parent, false);
viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.getTextView().setText(WORDS[position]);
return view;
}
private class ViewHolder {
private final View mRoot;
private TextView mText;
public ViewHolder(View root) {
mRoot = root;
}
public TextView getTextView() {
if (mText == null) {
mText = (TextView) mRoot.findViewById(R.id.text);
}
return mText;
}
}
}
My list item xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
></TextView>
I answered a related question that might help you as it details how to make tabs with fragments. My suggestion is to use the separate fragments for each tab (I think it makes everything much easier), but depending on your implementation you may want to pursue another direction.
One thing I've noticed is that you should do this:
mRoot = inflater.inflate(R.layout.tabs_fragment, container, false);
instead of this
mRoot = inflater.inflate(R.layout.tabs_fragment, null);
Check out this link:
http://www.doubleencore.com/2013/05/layout-inflation-as-intended/