ABS + ViewPager + manage orientation change - android

I am currently trying to implement an application with several Tabs and i must use also ViewPager.
The difficulty i'm facing is to manage screen orientation changes... Let me explain more in detail..
In portrait there is a player full screen (1fragment), in lanscape i want it to change to a list at the left and a player at the right (2fragment)
For now viewPager is blocking me, i've search through the internet and found nothing for this issu with abs + viewpager.
I think the problem can be related to the adapter. For now it takes a "Class" variable and instanciate the fragment from it.
Do you have an idea ?
Any suggestion is welcome ! Thanks !
Here is the code of my FragmentPagerAdapter :
public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context _context;
private final ActionBar _actionBar;
private final ViewPager _viewpager;
private final ArrayList<TabInfo> _tabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
_context = activity;
_actionBar = activity.getSupportActionBar();
_viewpager = pager;
_viewpager.setAdapter(this);
_viewpager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
_tabs.add(info);
_actionBar.addTab(tab);
notifyDataSetChanged();
}
#Override
public int getCount() {
return _tabs.size();
}
#Override
public Fragment getItem(int position) {
TabInfo info = _tabs.get(position);
return Fragment.instantiate(_context, info.clss.getName(), info.args);
}
#Override
public void onPageSelected(int position) {
_actionBar.setSelectedNavigationItem(position);
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < _tabs.size(); i++) {
if (_tabs.get(i) == tag) {
_viewpager.setCurrentItem(i);
}
}
}
}
Here is the SherlockFragmentActivity :
public class MainActivity extends SherlockFragmentActivity {
private ViewPager _viewPager;
private PagerTitleStrip _pagerStrip;
private ActionBar _actionBar;
private TabsAdapter _tabsAdapter;
private Tab _radioTab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_viewPager = (ViewPager) findViewById(R.id.viewpager);
_actionBar = getSupportActionBar();
_tabsAdapter = new TabsAdapter(this, _viewPager);
_radioTab = _actionBar.newTab().setCustomView(getTabIndicator(getString(R.string.radio_tab), android.R.drawable.ic_menu_manage));
_tabsAdapter.addTab(_radioTab, FragmentRadio.class, null);
}
private View getTabIndicator(String text, int drawable) {
View indicator = _inflater.inflate(R.layout.tabs, null);
((TextView) indicator.findViewById(R.id.tab_title)).setText(text);
((ImageView) indicator.findViewById(R.id.tab_icon)).setImageResource(drawable);
return indicator;
}
}
The class FragmentRadio :
public class FragmentRadio extends SherlockFragment {
private View _view;
public FragmentRadio() {
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
_view = inflater.inflate(R.layout.fragment_radio, container, false);
return _view;
}
}
The layout fragment_radio :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_radio_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/fragment_radio"
android:name="com.egdigital.testing.ContentRadioFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
The class ContentRadioFragment :
public class ContentRadioFragment extends SherlockFragment {
// log
private static final String TAG = ContentRadioFragment.class.getSimpleName();
// ihm
private View _view;
private Button _btnPlay;
private Button _btnPause;
private ImageView _imageViewCover;
private ScrollingTextView _textViewName;
private TextView _textViewState;
private SeekBar _seekBar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
_view = inflater.inflate(R.layout.content_radio, container, false);
_btnPlay = (Button) _view.findViewById(R.id.btn_play);
_btnPause = (Button) _view.findViewById(R.id.btn_pause);
_textViewName = (ScrollingTextView) _view.findViewById(R.id.tv_title);
_textViewState = (TextView) _view.findViewById(R.id.tv_buffering);
_seekBar = (SeekBar) _view.findViewById(R.id.seekBar1);
return _view;
}
}
And the layout content_radio is a normal layout

Related

ViewPager inside Listview for all the rows

My main objective is to create a listview, in each row a viewpager with a "ImageWordFragment" in each page, which cotains an Imageview.
Please DON'T tell me not to use viewpager inside a listview. A lots of apps are doing it, just help get to my goal.
I tried setting "setId()" but it prompts a null exception in the ViewPager variable inside the "getView" function.
The problem is the the first viewpager works in the first row of the listview. But the rest of it doesn't.
This is the xml of "fragment_word_image.xml":
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:text="LALA"/>
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_grey"/>
</LinearLayout>
This is the xml of "item_word.xml":
<LinearLayout
android:id="#+id/moreInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="200dp" />
</LinearLayout>
This is the adapter:
public class WordAdapter extends BaseAdapter {
private AppCompatActivity activity;
private LayoutInflater inflater;
private List<Word> wordItems;
public WordAdapter(AppCompatActivity activity, List<Word> wordItems) {
this.activity = activity;
this.wordItems = wordItems;
}
#Override
public int getCount() {
return wordItems.size();
}
#Override
public Word getItem(int position) {
return wordItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null) {
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_word, parent, false);
}
FrameLayout container = (FrameLayout) convertView.findViewById(R.id.container);
TextView type = (TextView) convertView.findViewById(R.id.type);
TextView name = (TextView) convertView.findViewById(R.id.name);
ImageView progress = (ImageView) convertView.findViewById(R.id.progress);
final LinearLayout moreInfo = (LinearLayout) container.findViewById(R.id.moreInfo);
ViewPager pager = (ViewPager) convertView.findViewById(R.id.viewPager);
// Getting word data
final Word w = wordItems.get(position);
//Pager
WordPagerAdapter adapter = new WordPagerAdapter(activity.getSupportFragmentManager(), activity, pager);
Bundle args1 = new Bundle();
args1.putString(ImageWordFragment.ARG_LINK, w.getImage());
adapter.addTab(R.string.title_section1, ImageWordFragment.class, args1);
Bundle args2 = new Bundle();
args2.putString(ImageWordFragment.ARG_LINK, w.getImage());
adapter.addTab(R.string.title_section1, ImageWordFragment.class, args2);
Bundle args3 = new Bundle();
args3.putString(ImageWordFragment.ARG_LINK, w.getImage());
adapter.addTab(R.string.title_section1, ImageWordFragment.class, args3);
//Notify Changes
adapter.notifyTabsChanged();
return convertView;
}
private class WordPagerAdapter extends FragmentStatePagerAdapter {
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private final Context mContext;
private final FragmentManager mFragmentManager;
private final ViewPager mViewPager;
final class TabInfo {
private final Class<?> mClass;
private final Bundle mArgs;
private final int mTitleRes;
TabInfo(Class<?> fragmentClass, Bundle args, int titleRes) {
mClass = fragmentClass;
mArgs = args;
mTitleRes = titleRes;
}
}
public WordPagerAdapter(FragmentManager fm, Context context, ViewPager pager) {
super(fm);
mFragmentManager = fm;
mContext = context;
//Setup view pager
mViewPager = pager;
mViewPager.setAdapter(this);
}
public void addTab(int titleRes, Class<?> fragmentClass, Bundle args) {
mTabs.add(new TabInfo(fragmentClass, args, titleRes));
}
public void notifyTabsChanged() {
notifyDataSetChanged();
}
public void setCurrentItem(int position) {
mViewPager.setCurrentItem(position);
}
public void setOffscreenPageLimit(int pages) {
mViewPager.setOffscreenPageLimit(pages);
}
#Override
public Fragment getItem(int position) {
TabInfo tab = mTabs.get(position);
return Fragment.instantiate(mContext, tab.mClass.getName(), tab.mArgs);
}
#Override
public int getCount() {
return mTabs.size();
}
}
}
Thsi is the fragment:
public class ImageWordFragment extends Fragment {
public static final String ARG_LINK = "ARG_LINK";
#InjectView(R.id.imageView)
ImageView imageView;
String imageUrl;
public ImageWordFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageUrl = getArguments().getString(ARG_LINK);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_word_image, container, false);
ButterKnife.inject(this, rootView);
new ImageLoadTask(imageUrl, imageView);
return rootView;
}
}
A couple of experiments indicate this is probably caused by your ViewPagers all having the same id (from the XML). Have you tried generating ids at runtime using View.generateViewId()?

Change data in listview at fragment

I have create a listview in a fragment in a tab in Android 2.3. I want to change the data in listview when I click the tab. For example, in "tab1" I can see "1,2,3" in listview, then I click to "tab2" and click back to "tab1", the listview change to show "a,b,c". I have create a refresh() method, and call it in onPageSelected, but it always got NullPointerException.
Here is my code:
List_View
public class List_View extends ListFragment{
protected ArrayAdapter listAdapter;
private ArrayList<String> items = new ArrayList<String>();
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.list, container, false);
items.add("1");
items.add("2");
items.add("3");
listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
setListAdapter(listAdapter);
return rootView;
}
public void refresh(){
items.clear();
listAdapter.notifyDataSetChanged();
items.add("a");
items.add("b");
items.add("c");
listAdapter.notifyDataSetChanged();
}
}
TabsAdapter
public class TabsAdapter extends FragmentStatePagerAdapter implements TabListener, OnPageChangeListener{
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private final String TAG = "";
private List_View list_view;
static final class TabInfo{
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args){
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ActionBar bar, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = bar;
mViewPager = pager;
mViewPager.setOffscreenPageLimit(0);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(Tab tab, Class<?> clss, Bundle args){
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
#Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
list_view.refresh();
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
Log.v(TAG, "clicked");
Object tag = tab.getTag();
for (int i = 0; i<mTabs.size(); i++){
if (mTabs.get(i) == tag){
mViewPager.setCurrentItem(i);
}
}
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
#Override
public int getCount() {
return mTabs.size();
}
}
I have create a refresh() method, and call it in onPageSelected, but
it always got NullPointerException
You have
private List_View list_view;
And you have
list_view.refresh();
But i don't see any code that initialized list_view.
Fragment to Fragment communication is done through the associated Activity.
http://developer.android.com/training/basics/fragments/communicating.html
So use a interface as a callback to the activity from fragment in tab2 and then communicate to List_View and change the list accordingly.

black fragment content when changing tab back

I have a fragment activity with TabHost and ViewPager inside it.
There are two tabs for the activity: the List tab and the Map tab.
On the List tab I've got list of my data (some institutions) and on the Map tab (using Google Maps API) I am displaying that institutions on the map with markers.
When activity is opened default tab is List. Swiping from right to left, or selecting Map tab brings me to the Map with markers.
The problem is, when I'm selecting the List tab again I've got a black content in stead of ListView and it's items. However, when from the List tab I select the Map tab again, Map shows correctly.
Here is activity source:
public class Institutions extends FragmentActivity {
public static final int TAB_LIST = 0;
public static final int TAB_MAP = 1;
private TabHost mTabHost;
private ViewPager mViewPager;
private TabsAdapter mTabsAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.institutions);
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(1);
mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
View v = createTab(TAB_LIST);
mTabsAdapter.addTab(mTabHost.newTabSpec("list").setIndicator(v),
InstitutionList.class, null);
v = createTab(TAB_MAP);
mTabsAdapter.addTab(mTabHost.newTabSpec("map").setIndicator(v),
InstitutionMap.class, null);
TextView activity_title = (TextView) findViewById(R.id.activity_title);
activity_title.setText(getIntent().getStringExtra(
Institution.INSTITUTION_TITLE));
}
private View createTab(int type) {
View v = getLayoutInflater().inflate(R.layout.tab, null);
TextView label = (TextView) v.findViewById(R.id.label);
ImageView icon = (ImageView) v.findViewById(R.id.icon);
icon.setVisibility(View.GONE);
icon.getLayoutParams().width = 1;
icon.getLayoutParams().height = 1;
switch (type) {
case TAB_LIST:
label.setText(getString(R.string.list_title));
break;
case TAB_MAP:
label.setText(getString(R.string.map_title));
break;
default:
break;
}
return v;
}
}
Here is the source for TabsAdapter:
public class TabsAdapter extends FragmentStatePagerAdapter implements
TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<? extends Fragment> clss;
private final Bundle args;
private Tab tab;
TabInfo(Class<? extends Fragment> _class, Bundle _args) {
clss = _class;
args = _args;
tab = null;
}
}
static class TabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public TabFactory(Context context) {
mContext = context;
}
#Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabsAdapter(FragmentActivity activity, TabHost tabHost,
ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<? extends Fragment> clss,
Bundle args) {
tabSpec.setContent(new TabFactory(mContext));
TabInfo info = new TabInfo(clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
if (info.tab == null) {
info.tab = (Tab) Fragment.instantiate(mContext,
info.clss.getName(), info.args);
}
return info.tab;
}
#Override
public void onTabChanged(String tabId) {
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
for (int i = 0; i < getCount(); i++) {
if (i == position)
continue;
Tab t = mTabs.get(i).tab;
if (t != null) {
t.onTabUnselected();
}
}
}
#Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
}
#Override
public void onPageScrollStateChanged(int state) {
}
}

Android Viewpager Tabs updating tab fragment

I have an Activity which scrapes a webpage in a CustomLoader.
When loader finished I want to update the contents of 3 tabs with the data retrieved.
I'm using the sample code provided by android dev samples to implement the Viewpager/Tabs/Fragments on the activity.
When the fragment is created for the tab the onCreateView is correctly called, all the widgets on the view are correctly located and mapped to the variables.
However, when I attempt to find the fragment from the Activity and call a method on the fragment to update its contents the variables are null. Furthermore, calling getView also returns null - The instance of the fragment I'm retrieving from the TabsAdapter is not the correct instantiated instance ?
I've cut the code down to a single tab fragment, code in question is the call from onLoaderFinished to update the fragment.
All 3 tab fragments will be populated with data from a single loader, hence the loader being on the activity, not on the fragments. I just need a way to tell the fragments to paint their new data.
public class InfoBloodStocksActivity extends SherlockFragmentActivity
implements LoaderManager.LoaderCallbacks<BloodStocksLoaderResponse> {
TabHost mTabHost;
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.info_bloodstocks_tabpager);
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
mViewPager = (ViewPager)findViewById(R.id.infoBloodStocksTabPager);
mViewPager.setOffscreenPageLimit(3);
mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
mTabsAdapter.addTab(mTabHost.newTabSpec("Daily stock").setIndicator("Daily stocks"),
InfoBloodStocksPageFragment.class, null);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
}
loadStockDetailsFromWebsite();
}
private void loadStockDetailsFromWebsite() {
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getSupportLoaderManager().initLoader(0, null, this);
}
#Override
public Loader<BloodStocksLoaderResponse> onCreateLoader(int arg0, Bundle arg1) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader with no arguments, so it is simple.
return new BloodStocksCustomLoader(this);
}
#Override
public void onLoadFinished(Loader<BloodStocksLoaderResponse> loader, BloodStocksLoaderResponse response) {
if (response.isNewStocksLoaded()) {
InfoBloodStocksPageFragment fragment = (InfoBloodStocksPageFragment) mTabsAdapter.getItem(0);
fragment.setNewImage(response.getDailyStocksImageURL());
}
}
#Override
public void onLoaderReset(Loader<BloodStocksLoaderResponse> arg0) {
// TODO Auto-generated method stub
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("tab", mTabHost.getCurrentTabTag());
}
/**
* This is a helper class that implements the management of tabs and all
* details of connecting a ViewPager with associated TabHost. It relies on a
* trick. Normally a tab host has a simple API for supplying a View or
* Intent that each tab will show. This is not sufficient for switching
* between pages. So instead we make the content part of the tab host
* 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
* view to show as the tab content. It listens to changes in tabs, and takes
* care of switch to the correct paged in the ViewPager whenever the selected
* tab changes.
*/
public static class TabsAdapter extends FragmentPagerAdapter
implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final String tag;
private final Class<?> clss;
private final Bundle args;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(Context context) {
mContext = context;
}
#Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
#Override
public void onTabChanged(String tabId) {
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
}
I'm calling setNewImage from the activity.
public class InfoBloodStocksPageFragment extends SherlockFragment {
private ImageView mImageView;
private ProgressBar mProgress;
private TextView mTitle;
private TextView mDescriptionText;
private String mImageURL;
private ImageLoader mImageLoader = ImageLoader.getInstance();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.info_bloodstocks_page, container, false);
mImageView = (ImageView)view.findViewById(R.id.bloodStocksPageImage);
mProgress = (ProgressBar)view.findViewById(R.id.bloodStocksPageProgress);
mTitle = (TextView)view.findViewById(R.id.bloodStockPageTitle);
mDescriptionText = (TextView)view.findViewById(R.id.bloodStocksPageText);
mProgress.setVisibility(View.VISIBLE);
mDescriptionText.setVisibility(View.GONE);
return view;
}
public void setNewImage(String imageURL) {
// why is mImageView null here ?
// why does getView() return null here ?
View view = getView();
mImageView = (ImageView)view.findViewById(R.id.bloodStocksPageImage);
DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.loading_stock_figures)
.cacheOnDisc()
.imageScaleType(ImageScaleType.EXACT)
.build();
mImageLoader.displayImage(imageURL, mImageView, displayImageOptions, new ImageLoadingListener() {
#Override
public void onLoadingStarted() {
mProgress.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(FailReason failReason) {
String message = null;
switch (failReason) {
case IO_ERROR:
message = "Input/Output error";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
mProgress.setVisibility(View.GONE);
mImageView.setImageResource(android.R.drawable.ic_delete);
}
#Override
public void onLoadingComplete() {
mProgress.setVisibility(View.GONE);
Animation anim = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in);
mImageView.setAnimation(anim);
anim.start();
}
#Override
public void onLoadingCancelled() {
// Do nothing
}
});
}
}
I've just started using http://square.github.com/otto/ for doing this. The documentation on the site should be enough to get you started with it.

Fragment is not restoring its state in a viewpager when back is pressed and reopened

I am trying to keep a view pager inside a fragment. And the View pager itself contains 3 other fragment. This is the Root fragment which contain the view pager
import android.support.v13.app.FragmentPagerAdapter;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import com.android.browser1.UI.ComboViews;
public class MyFragment extends Fragment implements
TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener, CombinedBookmarksCallbacks {
private TabHost mTabHost;
private ViewPager mViewPager;
public static final String EXTRA_COMBO_ARGS = "combo_args";
Bundle bundle;
Bundle extra;
public static final String EXTRA_INITIAL_VIEW = "initial_view";
public static BookmarkFragment bookmarkFragmentForPageA = null;
public static BookmarkFragment bookmarkFragmentForPageB = null;
Controller controller;
TabsAdapter mTabsAdapter;
FirstFragment first;
SecondFragment seconde;
ThirdFragment third;
public void setBundle(Bundle bundle) {
extra = bundle;// getActivity().getIntent().getExtras();
this.bundle = extra.getBundle(EXTRA_COMBO_ARGS);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mTabHost.setup();
mViewPager.setOffscreenPageLimit(2);
mTabsAdapter = new TabsAdapter(getActivity(), mTabHost, mViewPager);
new setAdapterTask().execute();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bookmark_view_pager, null);
mTabHost = (TabHost) view.findViewById(R.id.tabHost);
mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
view.setBackgroundColor(Color.BLACK);
return view;
}
private class setAdapterTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void result) {
String bookmark = getResources().getString(R.string.tab_bookmarks);
String history = getResources().getString(R.string.tab_history);
String scrapmemo = getResources().getString(R.string.tab_snapshots);
mTabsAdapter.addTab(
mTabHost.newTabSpec(bookmark).setIndicator(bookmark), BrowserBookmarksPage.class, null);
mTabsAdapter.addTab(
mTabHost.newTabSpec(history).setIndicator(history), BrowserHistoryPage.class, null);
mTabsAdapter.addTab(
mTabHost.newTabSpec(scrapmemo).setIndicator(scrapmemo), BrowserSnapshotPage.class, null);
String svStr = extra.getString(EXTRA_INITIAL_VIEW, null);
ComboViews startingView = svStr != null ? ComboViews.valueOf(svStr)
: ComboViews.Bookmarks;
switch (startingView) {
case Bookmarks:
mTabHost.setCurrentTab(0);
mViewPager.setCurrentItem(0);
break;
case History:
mTabHost.setCurrentTab(1);
mViewPager.setCurrentItem(1);
break;
case ScrapMemo:
mTabHost.setCurrentTab(2);
mViewPager.setCurrentItem(2);
break;
}
}
}
public void onTabChanged(String tag) {
ComboViews startingView = tag != null ? ComboViews.valueOf(tag)
: ComboViews.Bookmarks;
switch (startingView) {
case First:
mTabHost.setCurrentTab(0);
break;
case Second:
mTabHost.setCurrentTab(1);
break;
case Third:
mTabHost.setCurrentTab(2);
break;
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
this.mTabHost.setCurrentTab(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
public class TabsAdapter extends FragmentStatePagerAdapter
implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
final class TabInfo {
private final String tag;
private final Class clss;
private final Bundle args;
TabInfo(String _tag, Class _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(Context context) {
mContext = context;
}
#Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabsAdapter(Activity activity, TabHost tabHost, ViewPager pager) {
super(activity.getFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
mViewPager.setOffscreenPageLimit(3);
}
public void addTab(TabHost.TabSpec tabSpec, Class clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
getItem(0);
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
Fragment fr = null;
TabInfo info = mTabs.get(position);
// Create a new fragment if necessary.
switch (position) {
case 0:
fr = new FirstFragment();
fr.setArguments(info.args);
break;
case 1:
fr = new SecondFragment ();
fr.setArguments(info.args);
break;
case 2:
fr = new ThirdFragment ();
fr.setArguments(info.args);
break;
default:
fr = new FirstFragment ();
fr.setArguments(info.args);
break;
}
return fr;
}
#Override
public int getItemPosition(Object object) {
if (object instanceof FirstFragment
|| object instanceof SecondFragment
|| object instanceof ThirdFragment )
return POSITION_NONE;
return POSITION_UNCHANGED;
}
#Override
public void onTabChanged(String tabId) {
// called when the user clicks on a tab.
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
}
And when I attach this fragment in my activity for the first time we can see all the three fragment by swiping but after the back press we remove the fragment. After that again I attach the fragment in the same activity at run time but only first 2 fragments are visible and the content of 3rd one is empty.
I am trying to keep a view pager inside a fragment. And the View pager itself contains 3 other fragment.
Sorry, but fragments inside of other fragments is officially not supported, as indicated by Dianne Hackborn, a core Android team member.

Categories

Resources