Reputation: 2039
I'm trying to implement Tabs. The Tabs will contain the exact same layout and the same fragment with only one difference - the API URL! (e.g. Trending/Newest). My Code:
TabFragment
public class TabFragments extends Fragment implements OnPageChangeListener,
OnTabChangeListener {
private TabHost tabHost;
private int currentTab = 0;
private ViewPager viewPager;
private TabFragmentPageAdapter pageAdapter;
private List<Fragment> fragments;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tabhost, null);
tabHost = (TabHost) rootView.findViewById(android.R.id.tabhost);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
viewPager.setOnPageChangeListener(this);
//Create correct fragment
fragments=new ArrayList<>();
fragments.add(new ItemStreamFragment());
fragments.add(new ItemStreamFragment());
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
pageAdapter = new TabFragmentPageAdapter(getChildFragmentManager(),
fragments);
pageAdapter.notifyDataSetChanged();
viewPager.setAdapter(pageAdapter);
setupTabs();
}
private void setupTabs() {
tabHost.setup();
tabHost.addTab(newTab(R.string.tab_1_item));
tabHost.addTab(newTab(R.string.tab_2_item));
for (int i = 0; i < tabHost.getTabWidget().getChildCount(); i++) {
tabHost.getTabWidget().getChildAt(i)
.setBackgroundColor(Color.parseColor("#304c58"));
// tabHost.setBackgroundResource(R.drawable.tab_selector);
final View view = tabHost.getTabWidget().getChildTabViewAt(i);
final View textView = view.findViewById(android.R.id.title);
((TextView) textView).setTextColor(Color.parseColor("#e2ebf0"));
((TextView) textView).setSingleLine(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
tabHost.getTabWidget().getChildAt(i)
.findViewById(android.R.id.icon);
tabHost.getTabWidget().getChildAt(i).getLayoutParams().height = 75;
} else {
if (view != null) {
// reduce height of the tab
view.getLayoutParams().height *= 0.77;
if (textView instanceof TextView) {
((TextView) textView).setGravity(Gravity.CENTER);
textView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
textView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
}
}
}
}
tabHost.setOnTabChangedListener(TabFragments.this);
tabHost.setCurrentTab(currentTab);
}
private TabSpec newTab(int titleId) {
TabSpec tabSpec = tabHost.newTabSpec(getString(titleId));
tabSpec.setIndicator(getString(titleId));
tabSpec.setContent(new TabFactory(getActivity()));
return tabSpec;
}
@Override
public void onPageScrollStateChanged(int position) {
}
@Override
public void onPageScrolled(int position, float arg1, int arg2) {
}
@Override
public void onPageSelected(int position) {
tabHost.setCurrentTab(position);
}
@Override
public void onTabChanged(String tabId) {
currentTab = tabHost.getCurrentTab();
viewPager.setCurrentItem(currentTab);
}
@SuppressWarnings("unused")
private void updateTab() {
switch (currentTab) {
case 0:
ItemStreamFragment login = (ItemStreamFragment) fragments.get(currentTab);
break;
case 1:
ItemStreamFragment register = (ItemStreamFragment) fragments
.get(currentTab);
break;
}
}
class TabFactory implements TabContentFactory {
private final Context context;
public TabFactory(Context context) {
this.context = context;
}
@Override
public View createTabContent(String tag) {
View v = new View(context);
v.setMinimumHeight(0);
v.setMinimumWidth(0);
return v;
}
}
}
TabFragmentPageAdapter
public class TabFragmentPageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public TabFragmentPageAdapter(FragmentManager fm, List<Fragment> fragments
) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
Fragment fragment = fragments.get(position);
Bundle args = new Bundle();
args.putInt("position", position);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
And finally ItemStreamFragment
public class ItemStreamFragment extends Fragment {
private String mApiUrl = "http://api.eese.com:8080/ICDS_API/v1/reco.getNewest/?page=0&limit=13×tamp=2015-07-02+10%3A34%3A07&lang_key=en";
private final String mImages = "http://d30q95ofpjr96w.cloudfront.net/";
private ItemStream[] mObjectItem;
private int mPosition = 0;
public ItemStreamAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
if (bundle != null) {
mPosition = bundle.getInt("position", 0);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_itemstream, container, false);
view.setId(mPosition);
getStream(mPosition);
return view;
}
private void getStream(int position) {
switchUrl(position);
new GetRequestTask(new OnTaskCompleted() {
@Override
public void onTaskCompleted(String result) {
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonResults = jsonObject.getJSONArray("results");
final int resultLength = jsonResults.length();
mObjectItem = new ItemStream[resultLength];
for (int i = 0; i < resultLength; i++) {
JSONObject item = jsonResults.getJSONObject(i);
mObjectItem[i] = new ItemStream(item.getInt("id"), item.getString("title"), mImages + "" + item.getString("thumbnail") + ".374x210." + item.getString("thumbnail_type"));
}
if (getActivity() != null) {
mAdapter = new ItemStreamAdapter(getActivity(), R.layout.list_itemstream, mObjectItem);
ListView scrollView = (ListView) getActivity().findViewById(R.id.itemstream_trend);
scrollView.setAdapter(mAdapter);
}
} catch (Exception ex) {
}
}
}).execute(mApiUrl);
}
//Needs to be tuned
private void switchUrl(int position) {
switch (position) {
case 0:
mApiUrl = "http://api.eese.com:8080/ICDS_API/v1/reco.getTrending/?page=0&limit=13×tamp=2015-07-02+10%3A34%3A07&lang_key=en";
break;
case 1:
mApiUrl = "http://api.eese.com:8080/ICDS_API/v1/reco.getNewest/?page=0&limit=13×tamp=2015-07-02+10%3A34%3A07&lang_key=en";
break;
}
}
}
And here you see what happens:
(Sry for the overlay :) )
The thing is that the first Tab is loaded with data but the second tab stays empty (it shouldn't be empty though). Not sure what is wrong here. Would be cool if you can point me in the right direction :)
Upvotes: 0
Views: 1940
Reputation: 2039
Fixed the problem:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_itemstream, container, false);
view.setId(mPosition);
getStream(mPosition,view);
return view;
}
private void getStream(int position, final View view) {
switchUrl(position);
new GetRequestTask(new OnTaskCompleted() {
@Override
public void onTaskCompleted(String result) {
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonResults = jsonObject.getJSONArray("results");
final int resultLength = jsonResults.length();
mObjectItem = new ItemStream[resultLength];
for (int i = 0; i < resultLength; i++) {
JSONObject item = jsonResults.getJSONObject(i);
mObjectItem[i] = new ItemStream(item.getInt("id"), item.getString("title"), mImages + "" + item.getString("thumbnail") + ".374x210." + item.getString("thumbnail_type"));
}
if (getActivity() != null) {
mAdapter = new ItemStreamAdapter(getActivity(), R.layout.list_itemstream, mObjectItem);
ListView scrollView = (ListView) view.findViewById(R.id.itemstream_trend);
scrollView.setAdapter(mAdapter);
}
} catch (Exception ex) {
}
}
}).execute(mApiUrl);
}
Just added view to the method getStream. Now it is working! What do you think about this solution?
Upvotes: 0
Reputation: 6963
For using Tabs in material design you should use TabLayout from design support library. Here is the tutorial from where you can learn this new approach.
As far as loading fragment is concern, you second fragment will be loaded with first this is complete different discussion with viewpager, so you need to have different url for each fragment and don't create fragment using new Operator. Instead create static getInstance() in Fragment class and pass the url from there and using Fragment#setArgument(Bundle) get new Fragment instance. When fragment view is created i.e in onViewCreated(...) get arguments from bundle in your case String url and call webservice which will return the respective response.
Upvotes: 1