0

在我的应用程序中,我使用 FragmentActivity 设置了几个选项卡,并在选项卡旁边设置了一个按钮,用于激活幻灯片菜单。目前我有两个片段显示在标签 1 和 2 中。标签 1 的片段包含一个 v2 Google 地图,第二个只是一个空白屏幕。

在此处输入图像描述 在此处输入图像描述

但是,当我激活我的幻灯片菜单时,我得到了非常不同的行为,我现在已经在几个项目中使用了这个幻灯片菜单库,没有任何问题。当我在显示片段 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();
        }
    }
}   
 }
4

2 回答 2

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

于 2013-05-10T11:23:50.877 回答
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;
        }
    }
}
于 2013-05-24T16:01:55.113 回答