在我的应用程序中,我使用FragmentActivity设置了一些标签,并在标签旁边设置了一个按钮,用于激活幻灯片菜单。目前我有两个片段显示在选项卡1和2中。选项卡1的片段包含v2 Google Map,第二个片段只是一个空白屏幕。
然而,当我激活我的幻灯片菜单时,我得到了非常不同的行为,我现在已经将这个幻灯片菜单库用于几个项目而没有任何问题。当我显示片段2时激活幻灯片菜单它可以正常工作但是当显示片段1(地图视图)时,激活幻灯片菜单会使地图变黑并在幻灯片菜单关闭时再次显示地图。
以下是我设置标签
的代码XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="fill_parent"
android:layout_height="55dp"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/linearLayout1"
android:orientation="vertical" >
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</TabWidget>
</LinearLayout>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/linearLayout1" >
<FrameLayout
android:id="@+id/tab_1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<FrameLayout
android:id="@+id/tab_2"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<FrameLayout
android:id="@+id/tab_3"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<FrameLayout
android:id="@+id/tab_4"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
</RelativeLayout>
</TabHost>
JAVA
public class TabsFragment extends Fragment implements OnTabChangeListener {
private static final String TAG = "FragmentTabs";
public static final String TAB_MAP = "Map";
public static final String TAB_VENUES = "Venus";
public static final String TAB_GENRE = "Gap";
public static final String TAB_TICKETS = "Titus";
private View mRoot;
private TabHost mTabHost;
int mCurrentTab;
Button slide_btn;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mRoot = inflater.inflate(R.layout.tabs_fragment, null);
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(0);
// manually start loading stuff in the first tab
updateTab(TAB_MAP, R.id.tab_1);
}
private void setupTabs() {
mTabHost.setup(); // important!
mTabHost.addTab(newTab(TAB_MAP, R.id.tab_1, R.drawable.tab_home));
mTabHost.addTab(newTab(TAB_VENUS, R.id.tab_2, R.drawable.tab_home));
mTabHost.addTab(newTab(TAB_GAP, R.id.tab_3, R.drawable.tab_home));
mTabHost.addTab(newTab(TAB_TITUS, R.id.tab_4, R.drawable.tab_home));
}
private TabSpec newTab(String tag, int tabContentId, int drawableId) {
Log.d(TAG, "buildTab(): tag=" + tag);
View indicator = LayoutInflater.from(getActivity()).inflate(
R.layout.tabindicator,
(ViewGroup) mRoot.findViewById(android.R.id.tabs), false);
ImageView icon = (ImageView) indicator.findViewById(R.id.icon);
icon.setImageResource(drawableId);
TabSpec tabSpec = mTabHost.newTabSpec(tag);
tabSpec.setIndicator(indicator);
tabSpec.setContent(tabContentId);
return tabSpec;
}
@Override
public void onTabChanged(String tabId) {
Log.d(TAG, "onTabChanged(): tabId=" + tabId);
if (TAB_MAP.equals(tabId)) {
updateTab(tabId, R.id.tab_1);
mCurrentTab = 0;
return;
}
if (TAB_VENUS.equals(tabId)) {
updateTab(tabId, R.id.tab_2);
mCurrentTab = 1;
return;
}
if (TAB_GAP.equals(tabId)) {
updateTab(tabId, R.id.tab_3);
mCurrentTab = 2;
return;
}
if (TAB_TITUS.equals(tabId)) {
updateTab(tabId, R.id.tab_4);
mCurrentTab = 3;
return;
}
}
public void updateTab(String tabId, int placeholder) {
if (tabId.equals("Map")) {
FragmentManager fm = getFragmentManager();
if (fm.findFragmentByTag(tabId) == null) {
getFragmentManager().beginTransaction().add(placeholder, new MyFrag(), "Map").commit();
}
} else if (tabId.equals("Venus")) {
FragmentManager fm = getFragmentManager();
if (fm.findFragmentByTag(tabId) == null) {
getFragmentManager().beginTransaction().add(placeholder, new Green(), "Venus").commit();
}
} else if (tabId.equals("Gap")) {
} else if (tabId.equals("Titus")) {
}
}
public void slideMenu(){
if(isAdded()){
int width = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 200, getResources()
.getDisplayMetrics());
SlideoutActivity.prepare(getActivity(), R.id.inner_content, width);
Intent i = new Intent();
i.setClass(getActivity(), SlideMenuActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
getActivity().overridePendingTransition(0, 0);
}
}
}
然后我在FragmentActivity中渲染它,它有自己的包含片段的布局。
这是我用于地图的代码
XML
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/relativeLayout1"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical" >
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</LinearLayout>
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" >
<ImageButton
android:id="@+id/button3"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="@drawable/search_selected" />
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="@+id/button3"
android:ems="10"
android:inputType="text" >
</EditText>
</RelativeLayout>
JAVA
public class MyFrag extends Fragment {
GoogleMap map;
private static View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.main, container, false);
new LoadMap().execute();
} catch (InflateException e) {
/* map is already there, just return view as it is */
}
return view;
}
public class LoadMap extends AsyncTask<String, Integer, Location> {
LocationManager lm;
LatLng p = new LatLng(51.50703296721856, -0.11260986328125);
@Override
protected Location doInBackground(String... params) {
map = ((SupportMapFragment) getActivity()
.getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
LocationManager locationManager = (LocationManager) getActivity()
.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
p = new LatLng(location.getLatitude(), location.getLongitude());
return location;
}
protected void onPostExecute(Location location) {
try {
if (location != null) {
map.setMyLocationEnabled(true);
map.moveCamera(CameraUpdateFactory.newLatLng(p));
map.moveCamera(CameraUpdateFactory.zoomTo(15));
map.setOnCameraChangeListener(null);
} else {
Toast.makeText(getActivity(), "You got nada",
Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
答案 0 :(得分:0)
这是一个已知问题。
您可以在此处找到针对您案例的解决方法:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=4639
或在这里:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=4659
答案 1 :(得分:0)
虽然我在其他答案中发布的链接中找到了一些有用的位,但没有确凿的解决方案。我必须重新开始,并找到另一种方法来做到这一点,我已经完成了自定义水平ScrollView。我发布了代码,所以遇到这个问题的人都可以找到一个现成的解决方案来帮助他们。
代码在
之下Custom View
public class SlideMenu extends HorizontalScrollView {
public SlideMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public SlideMenu(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SlideMenu(Context context) {
super(context);
init(context);
}
void init(Context context) {
// remove the fading as the HSV looks better without it
setHorizontalFadingEdgeEnabled(false);
setVerticalFadingEdgeEnabled(false);
}
public void initViews(View[] children, int scrollToViewIdx, SizeCallback sizeCallback) {
// A ViewGroup MUST be the only child of the HSV
ViewGroup parent = (ViewGroup) getChildAt(0);
// Add all the children, but add them invisible so that the layouts are calculated, but you can't see the Views
for (int i = 0; i < children.length; i++) {
children[i].setVisibility(View.INVISIBLE);
parent.addView(children[i]);
}
// Add a layout listener to this HSV
// This listener is responsible for arranging the child views.
OnGlobalLayoutListener listener = new MyOnGlobalLayoutListener(parent, children, scrollToViewIdx, sizeCallback);
getViewTreeObserver().addOnGlobalLayoutListener(listener);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Do not allow touch events.
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Do not allow touch events.
return false;
}
/**
* An OnGlobalLayoutListener impl that passes on the call to onGlobalLayout to a SizeCallback, before removing all the Views
* in the HSV and adding them again with calculated widths and heights.
*/
class MyOnGlobalLayoutListener implements OnGlobalLayoutListener {
ViewGroup parent;
View[] children;
int scrollToViewIdx;
int scrollToViewPos = 0;
SizeCallback sizeCallback;
public MyOnGlobalLayoutListener(ViewGroup parent, View[] children, int scrollToViewIdx, SizeCallback sizeCallback) {
this.parent = parent;
this.children = children;
this.scrollToViewIdx = scrollToViewIdx;
this.sizeCallback = sizeCallback;
}
@Override
public void onGlobalLayout() {
final HorizontalScrollView me = SlideMenu.this;
// The listener will remove itself as a layout listener to the HSV
me.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// Allow the SizeCallback to 'see' the Views before we remove them and re-add them.
// This lets the SizeCallback prepare View sizes, ahead of calls to SizeCallback.getViewSize().
sizeCallback.onGlobalLayout();
parent.removeViewsInLayout(0, children.length);
final int w = me.getMeasuredWidth();
final int h = me.getMeasuredHeight();
// System.out.println("w=" + w + ", h=" + h);
// Add each view in turn, and apply the width and height returned by the SizeCallback.
int[] dims = new int[2];
scrollToViewPos = 0;
for (int i = 0; i < children.length; i++) {
sizeCallback.getViewSize(i, w, h, dims);
children[i].setVisibility(View.VISIBLE);
parent.addView(children[i], dims[0], dims[1]);
if (i < scrollToViewIdx) {
scrollToViewPos += dims[0];
}
}
// For some reason we need to post this action, rather than call immediately.
// If we try immediately, it will not scroll.
new Handler().post(new Runnable() {
@Override
public void run() {
me.scrollBy(scrollToViewPos, 0);
}
});
}
}
/**
* Callback interface to interact with the HSV.
*/
public interface SizeCallback {
public void onGlobalLayout();
public void getViewSize(int idx, int w, int h, int[] dims);
}
}
要使用它,您需要3 xml布局
Acts as a container to switch between side menu and activity
<your.pakage.name.SlideMenu
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="0px"
android:background="#00ffffff"
android:fadingEdge="none"
android:fadingEdgeLength="0px"
android:padding="0px"
android:scrollbars="none" >
<LinearLayout
android:id="@+id/top"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="0px"
android:background="#ffffffff"
android:orientation="horizontal"
android:padding="0px" >
</LinearLayout>
</your.pakage.name.SlideMenu >
在此处设计菜单内容
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 1" />
<TextView
android:id="@+id/2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 2" />
<TextView
android:id="@+id/text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 3" />
<TextView
android:id="@+id/text4"
android:layout_width="324dp"
android:layout_height="70dp"
android:text="Option 4" />
一些活动,我将使用ImageView激活幻灯片菜单
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/ic_launcher" />
</LinearLayout>
在您的活动中,您可以使用此代码使其正常工作
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
LayoutInflater inflater = LayoutInflater.from(this);
SlideMenu sMenu = (MyHorizontalScrollView) inflater.inflate(R.layout.xml_1, null);
setContentView(sMenu);
View menu = inflater.inflate(R.layout.xml_2, null);
View app = inflater.inflate(R.layout.xml_3, null);
ImageView menu_btn = (ImageView) app.findViewById(R.id.imageView1);
menu_btn.setOnClickListener(new ClickListenerForScrolling(sMenu, menu));
final View[] children = new View[] {menu, app};
int scrollToViewIdx = 1;
sMenu.initViews(children, scrollToViewIdx, new SizeCallbackForMenu(menu_btn));
}
//Then create some sub classes
class ClickListenerForScrolling implements OnClickListener {
SlideMenu scrollView;
View menu;
boolean menuOut = false;
public ClickListenerForScrolling(SlideMenu scrollView,
View menu) {
super();
this.scrollView = scrollView;
this.menu = menu;
}
@Override
public void onClick(View v) {
int menuWidth = menu.getMeasuredWidth();
menu.setVisibility(View.VISIBLE);
if (!menuOut) {
int left = 0;
scrollView.smoothScrollTo(left, 0);
} else {
int left = menuWidth;
scrollView.smoothScrollTo(left, 0);
}
menuOut = !menuOut;
}
}
static class SizeCallbackForMenu implements SizeCallback {
int btnWidth;
View btnSlide;
public SizeCallbackForMenu(View btnSlide) {
super();
this.btnSlide = btnSlide;
}
@Override
public void onGlobalLayout() {
//use this value to control how far the window will scroll horizontally
btnWidth = btnSlide.getMeasuredWidth();
}
@Override
public void getViewSize(int idx, int w, int h, int[] dims) {
dims[0] = w;
dims[1] = h;
final int menuIdx = 0;
if (idx == menuIdx) {
dims[0] = w - btnWidth;
}
}
}