I am a newbie in Android, how can I do something like that.
I extend TabActivity when to create Tabs like this but without that header.
If you want to implement the view you post here ,you can code the view by yourself:
the header is in the top ,and below the header ,a TabHost is needed ,below the TabHost,you put a viewpager contains two fragments to display your data,you can control your viewpager with method setCurrentItem when you click tabs.
Try this code
MainActivity
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import com.viewpagerindicator.CirclePageIndicator;
public class LauncherActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
pager.setAdapter(new GuidePagerAdapter(getSupportFragmentManager()));
indicator.setViewPager(pager);
}
}
ativity_main
<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:background="#drawable/background"
android:orientation="vertical"
>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#80000000"
android:orientation="vertical" >
<com.viewpagerindicator.CirclePageIndicator
android:id="#+id/indicator"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp" />
</LinearLayout>
</LinearLayout>
Adapter
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
public class GuidePagerAdapter extends FragmentStatePagerAdapter {
public GuidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
if (pos == 0)
return new Fragment1();
else
return new Fragment2();
}
#Override
public int getCount() {
return 2;
}
}
You can add two tabs on main_activity and on click of tab change the fragment in adapter.
Related
I've implemented an infinite ViewPager in situ https://github.com/JoachimR/AnyDayViewPager. However, instead of using a PagerTabStrip, I'd prefer to use a CoordinatorLayout with TabLayout. But when setting up the TabLayout with the viewpager, (I'm assuming because there are an "infinite number of ViewPager Fragments") the app gets stuck.
How can I solve this issue?
Here's the code
(the other files which I have not changed can be found at JoachimR/AnyDayViewPager, e.g., FragmentContent.java, CachingFragmentStatePagerAdapter.java, TimeUtils.java, etc)
MainActivity.java
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.design.widget.TabLayout;
import android.os.Bundle;
import java.util.Calendar;
public class MainActivity extends FragmentActivity {
private static Context mContext;
private CachingFragmentStatePagerAdapter adapterViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
ViewPager vpPager = (ViewPager) findViewById(R.id.vpPager);
adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
vpPager.setAdapter(adapterViewPager);
// set pager to current date
vpPager.setCurrentItem(TimeUtils.getPositionForDay(Calendar.getInstance()));
/** THIS IS WHERE THE ISSUES ARISE **/
TabLayout tabLayoutDiary = (TabLayout) findViewById(R.id.diary_tabs);
tabLayoutDiary.setupWithViewPager(vpPager);
}
public static class MyPagerAdapter extends CachingFragmentStatePagerAdapter {
private Calendar cal;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
#Override
public int getCount() {
return TimeUtils.DAYS_OF_TIME;
}
#Override
public Fragment getItem(int position) {
long timeForPosition = TimeUtils.getDayForPosition(position).getTimeInMillis();
return FragmentContent.newInstance(timeForPosition);
}
#Override
public CharSequence getPageTitle(int position) {
Calendar cal = TimeUtils.getDayForPosition(position);
return TimeUtils.getFormattedDate(mContext, cal.getTimeInMillis());
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:fab="http://schemas.android.com/tools">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="#+id/diary_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/vpPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
Possibly due to this bug: https://code.google.com/p/android/issues/detail?id=180027
TabLayout creates a TextView tab for each page in your ViewPager, rather than dynamically creating and recycling the TextViews. As you're seeing, this will just blow up if you try to fake out an infinite ViewPager.
Unfortunately, there's no fix for now. You can try using https://github.com/nshmura/RecyclerTabLayout which was linked on the bug, but I've not used it myself.
I want to create an Activity with tabs (probably using TabHost) that looks something like this:
This layout also has some buttons, checkboxes and a gridview, but I'm mostly interested to find out how I would have my tabs look like this, because by default they look something like this:
My problem is that I have no clue how to do it, I have made drawables for some UI components before, but this is something different, I think.
After quite some time I have figured how to get what I wanted, by trying out a lot of different ways to make tabs an I finally ended up using a TabLayout with a ViewPager.
I have made a Proof of Concept and it looks like this:
If anyone is interested in the code, this is the layout of the main activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="10">
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.2"/>
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4"
app:tabMode="fixed"
app:tabGravity="fill"
app:tabPaddingStart="2dp"
app:tabPaddingEnd="2dp"
app:tabPaddingTop="2dp"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5.8"/>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
The MainActivity.java:
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements FirstTabFragment.OnFragmentInteractionListener, SecondTabFragment.OnFragmentInteractionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
tabLayout.setSelectedTabIndicatorColor(Color.TRANSPARENT);
viewPager.setAdapter(new SectionPagerAdapter(getSupportFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
TabLayout.Tab tab = tabLayout.getTabAt(0);
RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.tab_layout_file1, tabLayout, false);
TextView tabTextView = (TextView) relativeLayout.findViewById(R.id.tab_title);
tabTextView.setText(tab.getText());
tab.setCustomView(relativeLayout);
TabLayout.Tab tab2 = tabLayout.getTabAt(1);
RelativeLayout relativeLayout2 = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.tab_layout_file2, tabLayout, false);
TextView tabTextView2 = (TextView) relativeLayout2.findViewById(R.id.tab_title);
tabTextView2.setText(tab2.getText());
tab2.setCustomView(relativeLayout2);
tab.select();
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public class SectionPagerAdapter extends FragmentPagerAdapter {
public SectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new FirstTabFragment();
case 1:
default:
return new SecondTabFragment();
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "First Tab";
case 1:
default:
return "Second Tab";
}
}
}
}
TabLayout1 (TabLayout2 is the same but uses shape2)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tab_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#drawable/shape1"
android:textColor="#android:color/white"/>
</RelativeLayout>
The shapes are just a red and a blue rectangle and and the Fragments are default
empty Fragments with the same color background as the shapes.
I have a project I'm trying to do. I ran into a little issue and I'm not sure how to get around it. Below is an image of the application so far.
What I would like it to do is when the user onclicks one of the list items, the part which says "Hello! It's Fragment2" changes to a new xml which I declared in the app. So if I click the ATO listItem, then the fragment on the right side should change to something like "Hello! It's ATO Fragment"
Here is my code so far:
AndroidListFragmentActivity:
package com.exercise.AndroidListFragment;
import android.app.Activity;
import android.os.Bundle;
public class AndroidListFragmentActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Fragment2:
package com.exercise.AndroidListFragment;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.fragment2, container, false);
}
}
MyListFragment1:
package com.exercise.AndroidListFragment;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MyListFragment1 extends ListFragment {
String[] options ={
"ATO",
"BETA",
"DELT",
"PHI DELT",
"SAE",
"SIG NU",
"FIJI",
"SIG CHI",
"PHI PSI"
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListAdapter myListAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, options);
setListAdapter(myListAdapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.listfragment1, container, false);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), getListView().getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show();
}
}
Fragment2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/fragment2text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello! It's Fragment2" />
</LinearLayout>
listfragment1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ListView android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="No data"/>
</LinearLayout>
main.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="horizontal" >
<fragment
android:name="com.exercise.AndroidListFragment.MyListFragment1"
android:id="#+id/fragment1"
android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />
<fragment
android:name="com.exercise.AndroidListFragment.Fragment2"
android:id="#+id/fragment2"
android:layout_weight="2"
android:layout_width="0px"
android:layout_height="match_parent" />
</LinearLayout>
Not sure what's the minimal fix to get your code working, but have you looked at using a Navigation Drawer to switch between the fragments? It looks to me like the example in the official docs matches pretty much exactly what you want to achieve.
A key is to have some kind of container for the currently displayed fragment (instead of using <fragment> like in your XML). For example:
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Then, switching fragments goes something like this:
Fragment fragment = new Fragment2();
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
Further reading: Add a Fragment to an Activity at Runtime in Android developer docs.
private void openFragment (int number) {
Fragment fragment = new Fragment();
switch (number) {
case FRAGMENT_1:
fragment = new *Fragment1*();
break;
case FRAGMENT_2:
fragment = new *Fragment2*();
break;
}
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_frame, fragment)
.commit();
}
I am trying to allow my app to call functions from my fragment classes in the fragmentactivity. However I am having a lot of issues just finding the fragment. Right now I can find one fragment by id which I think is the fragment hosting the tabs. But when I get the child fragment manager I get returned a null. Can anyone help?
This is the fragment activity
package com.example.profileactivity;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TabHost.TabSpec;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTabHost;
public class ProfileActivity extends FragmentActivity {
// Fragment TabHost as mTabHost
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this,getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("user").setIndicator("User",
getResources().getDrawable(R.drawable.ic_user_tab)),
UserProfileTab.class,null);
mTabHost.addTab(mTabHost.newTabSpec("payment").setIndicator("Payment",
getResources().getDrawable(R.drawable.ic_payment_tab)),
PaymentInfoTab.class,null);
}
public void buttonClick(View view){
FragmentManager fm = getSupportFragmentManager();
if(fm.findFragmentById(R.id.realtabcontent) == null){
Log.d("TABHOST", "didnt find fragment");
}
else{
Log.d("TABHOST", "found fragment");
//PaymentInfoTab paymentTab = (PaymentInfoTab)fm.findFragmentByTag("payment");
//paymentTab.boom();
if(fm.findFragmentById(R.id.realtabcontent).getChildFragmentManager().findFragmentByTag("payment") != null){
PaymentInfoTab paymentTab = (PaymentInfoTab)fm
.findFragmentById(R.id.realtabcontent)
.getChildFragmentManager()
.findFragmentByTag("payment");
paymentTab.boom();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.profile, menu);
return true;
}
}
This is the xml for the fragmentactivity.
<android.support.v4.app.FragmentTabHost
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:orientation="horizontal"
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/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
Try using the tag on the activity's FragmentManager directly.
The complete reference of your example seems to be this. Follow this example with more details, you will see that the writer keeps track of tabs and their tag.
I had the similar issue with fetching fragments after tab change which always returned null. Posting Runnable at the end of TabHost message queue did the trick:
tabHost.post(new Runnable() {
#Override
public void run() {
Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(tag);
fragment.updateList(newList);
}
});
i have created a new project and included the HoloEveryWhere library. Then I decided to add the ViewPageIndicator.
I copied all the code from ViewPageIndicator sample but it didn't work.
I tried using SherlockFragment but that didn't work either.
So I removed HoloEveryWhere from my project but apparently that wasn't the problem cause it still doesn't swipe.
edit:
this is my 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"
tools:context=".MainActivity" >
<com.viewpagerindicator.TabPageIndicator
android:id="#+id/indicator"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
you see, i just copied the two tags from the samples.
this is the main.java:
package com.example.test;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.TabPageIndicator;
public class MainActivity extends FragmentActivity {
private static final String[] CONTENT = new String[] { "Recent", "Artists", "Albums", "Songs", "Playlists", "Genres" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentPagerAdapter adapter = new GoogleMusicAdapter(getSupportFragmentManager());
ViewPager pager = (ViewPager)findViewById(R.id.pager);
pager.setAdapter(adapter);
TabPageIndicator indicator = (TabPageIndicator)findViewById(R.id.indicator);
indicator.setViewPager(pager);
}
class GoogleMusicAdapter extends FragmentPagerAdapter {
public GoogleMusicAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return TestFragment.newInstance(CONTENT[position % CONTENT.length]);
}
#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position % CONTENT.length];
}
#Override
public int getCount() {
return CONTENT.length;
}
}
}
Your layout is the source of your difficulty.
If you are going to use RelativeLayout, you need to specify where the widgets inside the RelativeLayout go. By default, they all go in the upper-left corner, and later children (your ViewPager) float over top of earlier children (your TabPageIndicator) on the Z axis. Hence, with your current layout, the user cannot touch your TabPageIndicator.
Either switch to a vertical LinearLayout or use the appropriate attributes (e.g., android:layout_below) to organize your widgets in the RelativeLayout so that they do not overlap.
Hierarchy View is a useful tool for helping you identify this sort of problem.