问题
My application has two tabs and I want to put it right on the ActionBar like this
However these tabs are always separated in lower level compare to Up button and menus as below:
I do not use:
android:uiOptions="splitActionBarWhenNarrow"
How can I achieve my actionbar like the first image? Thank you very much for any suggestion!
回答1:
I would suggest to make a custom layout for your action bar that will have two buttons or Imageviews that look like tabs and switch between fragments onClick(). Just have a popupMenu to reveal the rest of your menu Items.
I have done the layout and the sample Activity implementation:
Layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:showDividers="middle"
android:divider="@drawable/action_bar_divider"
android:dividerPadding="10dp"
android:weightSum="7">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_gravity="center_vertical"
android:orientation="vertical"
android:clickable="true"
android:onClick="imagesViewClick">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="IMAGES"
android:textColor="@android:color/white"
android:gravity="center"
android:layout_centerInParent="true"/>
<View
android:id="@+id/images_selected_view"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_alignParentBottom="true"
android:background="#427fed"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_gravity="center_vertical"
android:orientation="vertical"
android:clickable="true"
android:onClick="videosViewClick">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="VIDEOS"
android:textColor="@android:color/white"
android:gravity="center"
android:layout_centerInParent="true"/>
<View
android:id="@+id/videos_selected_view"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_alignParentBottom="true"
android:background="#427fed"
android:visibility="gone"/>
</RelativeLayout>
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_overflow"
android:layout_gravity="center_vertical"
android:layout_weight="1"/>
</LinearLayout>
And here's the full Activity Implementaion:
public class MainActivity extends ActionBarActivity{
private View imagesViewSelected;
private View videosViewSelected;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupActionBar();
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new ImagesFragment())
.commit();
}
}
private void setupActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowHomeEnabled(false);
ActionBar.LayoutParams lp1 = new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
View customNav = LayoutInflater.from(this).inflate(R.layout.layout_action_bar, null);
imagesViewSelected = customNav.findViewById(R.id.images_selected_view);
videosViewSelected = customNav.findViewById(R.id.videos_selected_view);
actionBar.setCustomView(customNav, lp1);
}
public static class ImagesFragment extends Fragment {
public ImagesFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
((TextView)rootView.findViewById(R.id.txt_fragment_locator)).setText("Images Fragment");
return rootView;
}
}
public static class VideosFragment extends Fragment {
public VideosFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
((TextView)rootView.findViewById(R.id.txt_fragment_locator)).setText("Videos Fragment");
return rootView;
}
}
public void imagesViewClick(View view){
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new ImagesFragment())
.commit();
imagesViewSelected.setVisibility(View.VISIBLE);
videosViewSelected.setVisibility(View.GONE);
}
public void videosViewClick(View view){
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new VideosFragment())
.commit();
imagesViewSelected.setVisibility(View.GONE);
videosViewSelected.setVisibility(View.VISIBLE);
}
}
You just have to implement the PopupMenu.
回答2:
I share my final code here, hope this help somebody:
MainActivity.java
package com.example.testfragments;
@SuppressLint("NewApi")
public class MainActivity extends FragmentActivity implements OnClickListener{
public static String FIRST_TAB_TAG = "first";
public static String SECOND_TAB_TAG = "second";
private Button imageTabButton;
private Button videosTabButton;
private Fragment imageFragment;
private Fragment videoFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
imageFragment = Fragment.instantiate(this, FirstFragment.class.getName());
getSupportFragmentManager().beginTransaction()
.add(R.id.container, imageFragment)
.commit();
}
setupTabs();
}
@Override public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.main, menu);
imageTabButton = (Button)findViewById(R.id.imagesTabBtn);
imageTabButton.setOnClickListener(this);
imageTabButton.setSelected(true);
videosTabButton = (Button)findViewById(R.id.videosTabBtn);
videosTabButton.setOnClickListener(this);
return true;
}
private void setupTabs() {
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setLogo(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(R.layout.custom_actionbar_layout);
}
/**
* A placeholder fragment to explore images
*/
public static class FirstFragment extends Fragment {
public FirstFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_attachment_galllery_images,
container, false);
return rootView;
}
}
/**
* A placeholder fragment to explore videos
**/
public static class SecondFragment extends Fragment {
public SecondFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_attachment_galllery_videos,
container, false);
return rootView;
}
}
@Override
public void onClick(View v) {
int viewId = v.getId();
FragmentTransaction sft;
switch (viewId) {
case R.id.imagesTabBtn:
// getSupportFragmentManager().beginTransaction()
// .replace(R.id.container, new FirstFragment())
// .commit();
if(!imageTabButton.isSelected()){
sft = this.getSupportFragmentManager().beginTransaction();
// Check if the fragment is already initialized
if (imageFragment == null) {
// If not, instantiate and add it to the activity
imageFragment = Fragment.instantiate(this, FirstFragment.class.getName());
sft.add(R.id.container, imageFragment, FIRST_TAB_TAG);
} else {
// If it exists, simply attach it in order to show it
sft.attach(imageFragment);
}
if (videoFragment != null) {
// Detach the fragment, because another one is being attached
sft.detach(videoFragment);
}
sft.commit();
imageTabButton.setSelected(true);
videosTabButton.setSelected(false);
}
break;
case R.id.videosTabBtn:
// getSupportFragmentManager().beginTransaction()
// .replace(R.id.container, new SecondFragment())
// .commit();
if(!videosTabButton.isSelected()){
sft = this.getSupportFragmentManager().beginTransaction();
// Check if the fragment is already initialized
if (videoFragment == null) {
// If not, instantiate and add it to the activity
videoFragment = Fragment.instantiate(this, SecondFragment.class.getName());
sft.add(R.id.container, videoFragment, SECOND_TAB_TAG);
} else {
// If it exists, simply attach it in order to show it
sft.attach(videoFragment);
}
if (imageFragment != null) {
// Detach the fragment, because another one is being attached
sft.detach(imageFragment);
}
sft.commit();
videosTabButton.setSelected(true);
imageTabButton.setSelected(false);
}
default:
break;
}
}
}
custom_actionbar_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"
android:divider="?android:dividerVertical"
android:showDividers="beginning|middle|end"
android:dividerPadding="10dp">
<RelativeLayout android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5">
<Button
android:id="@+id/imagesTabBtn"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:background="@drawable/abc_tab_indicator_ab_holo"
android:textColor="@color/abc_search_url_text_normal"
android:text="IMAGES" />
</RelativeLayout>
<RelativeLayout android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5">
<Button
android:id="@+id/videosTabBtn"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:background="@drawable/abc_tab_indicator_ab_holo"
android:text="VIDEOS" />
</RelativeLayout>
</LinearLayout>
By the way, here is the xml of abc_tab_indicator_ab_holo which I found in support library:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@android:color/transparent" />
<item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/abc_tab_selected_holo" />
<!-- Focused states -->
<item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/abc_list_focused_holo" />
<item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/abc_tab_selected_focused_holo" />
<!-- Pressed -->
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/abc_list_pressed_holo_dark" />
<item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/abc_tab_selected_pressed_holo" />
<!-- Focused states -->
<item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/abc_tab_unselected_pressed_holo" />
<item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/abc_tab_selected_pressed_holo" />
</selector>
来源:https://stackoverflow.com/questions/24604972/how-to-put-tabs-on-the-actionbar-same-level-with-up-button-and-menus