0

I want to display a google map API 2.0 inside as a ribbon above the data UI fragment and to give the user the possibility to expand the map to interact with it. Illustration: ribbon and expanded

Doing so, the user has the map to illustrate his position when it is in ribbon mode while when the user ewpands the map (covering 4/5 of the screen) he can use the map features.

How should I do that ? What are your though on it?

I was thinking about

  • a sliding drawer from top that contains the map
  • an overlaying "card UI" interface to display data over the map,
  • trying to mess with heigh and focus (but that's the way it was done for the screenshots and the user interaction cries for improvement)

Any advice?

Thank you for ideas and looking at it !

Disclaimer: I know this is iOS-like but I am transforming it toward native design, now the application uses ActionBarCompat but i needed to show you the wanted result ( and not the current state).

4

1 回答 1

0

如果有人需要,我就是这样做的:

  • 我定义了一个 LinearLayout 来拦截用户操作并控制地图扩展/收缩。
  • 我在相对布局中放置了一个 mapFragment v2.0。
  • 我在扩展缩小地图时定义滚动视图尺寸。

此片段的布局:

    <?xml version="1.0" encoding="utf-8"?>
<com.snapcar.rider.utils.LinearTouchEventLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:pj="http://schemas.android.com/apk/res/com.snapcar.rider"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_red"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/map_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
    </RelativeLayout>

    <ScrollView
        android:id="@+id/scrollView1"
        style="@style/sc_scroll_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="5" >

Layout content

    </ScrollView>
</com.snapcar.rider.utils.LinearTouchEventLayout>

线性布局的扩展:

    package com.snapcar.rider.utils;

import android.content.Context;
import android.support.v4.app.NotificationCompat.Action;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;


public class LinearTouchEventLayout extends LinearLayout {

    private static final String TAG = "LinearTouchEventLayout";



    RelativeLayout mapContainer;
    ScrollView mScroll;

    public LinearTouchEventLayout(Context context) {
        super(context);
        setLinearTouchEventLayoutListener((LinearTouchEventLayoutListener) context);
        for(int i=0; i<getChildCount(); ++i) {
            View nextChild = getChildAt(i);
            if (nextChild instanceof RelativeLayout) mapContainer = (RelativeLayout) nextChild;
            if (nextChild instanceof ScrollView) mScroll =  (ScrollView) nextChild;
        }
        Dbg.d(TAG, "first constructor ended");
        // TODO Auto-generated constructor stub
    }

    public LinearTouchEventLayout(Context context, AttributeSet aset) {
        super(context, aset);
        setLinearTouchEventLayoutListener((LinearTouchEventLayoutListener) context);
        for(int i=0; i<getChildCount(); ++i) {
            View nextChild = getChildAt(i);
            if (nextChild instanceof RelativeLayout) mapContainer = (RelativeLayout) nextChild;
            if (nextChild instanceof ScrollView) mScroll = (ScrollView) nextChild;
        }
        if (mapContainer == null) Dbg.d(TAG, "mapContainer is null");
        if (mScroll == null) Dbg.d(TAG, "mScroll is null");
        Dbg.d(TAG, "second constructor ended");
    }


    private boolean isMapExpand = false;

    public boolean isMapExpand() {
        return isMapExpand;
    }

    public void setMapExpand(boolean isMapExpand) {
        this.isMapExpand = isMapExpand;
    }

    public interface LinearTouchEventLayoutListener {
        void onTouch();

        void onShrinkMap();
    }

    private LinearTouchEventLayoutListener mListener;

    public void setLinearTouchEventLayoutListener(LinearTouchEventLayoutListener listener) {
        mListener = listener;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
//        Dbg.d(TAG,"Event - onInterceptTouchEvent");
        for(int i=0; i<getChildCount(); ++i) {
            View nextChild = getChildAt(i);
            if (nextChild instanceof RelativeLayout) mapContainer = (RelativeLayout) nextChild;
            if (nextChild instanceof ScrollView) mScroll =  (ScrollView) nextChild;
        }
        if (mapContainer != null && isPointInsideView(ev.getX(), ev.getY(), mapContainer))  Dbg.e(TAG, "inside mapContainer"); 
        if (mScroll != null && isPointInsideView(ev.getX(), ev.getY(), mScroll))  Dbg.e(TAG, "inside mScroll"); 

        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
//          Dbg.d(TAG,"ACTION_DOWN");
            if (mapContainer != null && isPointInsideView(ev.getX(), ev.getY(), mapContainer)) {
//              Dbg.e(TAG, "inside mapContainer"); 
                if (!isMapExpand && mListener != null) {
                    mListener.onTouch();
                    isMapExpand = !isMapExpand;
                    return true;
                } 
                if (isMapExpand) {
                    return false;
                }
            }
            if (mScroll != null && isPointInsideView(ev.getX(), ev.getY(), mScroll) && isMapExpand && mListener != null) {
                    mListener.onShrinkMap();
                    isMapExpand = !isMapExpand;
                    return true;
            }
            break;
        case MotionEvent.ACTION_MOVE:
//          Dbg.d(TAG,"ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
//          Dbg.d(TAG,"ACTION_UP");
            break;
        case MotionEvent.ACTION_SCROLL:
//          Dbg.d(TAG,"ACTION_SCROLL");
            break;

        }

        return false;
//        if (isMapExpand) { // just to be sure sure
//          onTouchEvent(ev);
//        }
//        return super.onInterceptTouchEvent(ev);
        //return false; //event get propagated
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
//        Dbg.d(TAG, "Event - dispatchTouchEvent");
//        if (isMapExpand) { //in this case we want to stop dispatching & handle the even ourself.
//          System.out.println("dispatchTouchEvent - Map is   E x p a n d e d");
//          onInterceptTouchEvent(ev);
//          return true; //the even will be consumed
//        } else { // Usual process
//          System.out.println("dispatchTouchEvent - Map is shrinked");
//          return super.dispatchTouchEvent(ev);
//        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
//      Dbg.d(TAG, "Event - onTouchEvent");
//      if (isMapExpand) {
//          System.out.println("onTouchEvent -  Map is E x p a n d e d  - onTouch");
//          //BookingFormFragment.this.shrinkMap();
//          return true;
//      } else {
//          System.out.println("onTouchEvent - usual process");
//          return super.onTouchEvent(event);
//      }
//      
        return super.onTouchEvent(event);
    }

    /**
     * Determines if given points are inside view
     * @param x - x coordinate of point
     * @param y - y coordinate of point
     * @param view - view object to compare
     * @return true if the points are within view bounds, false otherwise
     */
    boolean isPointInsideView (float x, float y, View view) {
        int location[] = new int[2];
        view.getLocationOnScreen(location);
        int viewX = view.getLeft();
        int viewY = view.getTop();
//      Dbg.d(TAG,"viewX = "+viewX);
//      Dbg.d(TAG,"viewY = "+viewY);
//      Dbg.d(TAG,"view.getWidth() = "+view.getWidth());
//      Dbg.d(TAG,"view.getHeight() = "+view.getHeight());
//      Dbg.d(TAG,"eventX = "+x);
//      Dbg.d(TAG,"eventY = "+y);

        //point is inside view bounds
        if(( x > viewX && x < (viewX + view.getWidth())) &&
                ( y > viewY && y < (viewY + view.getHeight()))){
//          Dbg.d(TAG, "Point is INSIDE view");
            return true;
        } else {
//          Dbg.d(TAG, "Point is OUT SIDE view");
            return false;
        }
    }


}

并且至少在片段类中有用的方法:

OnCreate 回调:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    Dbg.v(TAG, "- onCreateView bookingFormFragment");
    root = inflater.inflate(R.layout.fragment_booking_form, null);
    root.setOnClickListener(this);

    mScroll = (ScrollView) root.findViewById(R.id.scrollView1);

    /*
     * Map Fragment
     */
    FragmentManager fm = getChildFragmentManager();
    mapFragment = new CustomMapFragment();
    fm.beginTransaction().replace(R.id.map_fragment_container, mapFragment).commit();
things I need to set up the menu item and the scroll content
}

收缩/扩展方法:

private void shrinkMap() {

Dbg.d(TAG, "shrinkMap");

DropDownAnim anim = new DropDownAnim(mScroll, false);
anim.setDuration(300);
anim.setAnimationListener(new AnimationListener() {

    @Override
    public void onAnimationStart(Animation animation) {
        Dbg.d(TAG, "DropDownAnim - shrink start");
        isShrinking = true;
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        Dbg.d(TAG, "DropDownAnim shrink end");
        isShrinking = false;
        isMapShrinked = true;
        adjustMapPosAndZoom();
    }
});

getView().startAnimation(anim);
}

当然还有动画定义:

private class DropDownAnim extends Animation {
boolean down;
float maxRatio = 5;
float minRatio =  0.2f;

public DropDownAnim(View view, boolean down) {
    this.down = down;
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    float currentRatio;
    if (down) {
        currentRatio = maxRatio - (float) ((maxRatio - minRatio) * interpolatedTime);
    } else {
        currentRatio = minRatio + (float) ((maxRatio - minRatio) * interpolatedTime);
    }
    LinearLayout.LayoutParams param2 = new LinearLayout.LayoutParams(
            LayoutParams.MATCH_PARENT,
            0, (float) currentRatio);
    Dbg.d(TAG, "---   "+ currentRatio);
    mScroll.setLayoutParams(param2);
    root.requestLayout();
}

@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
    super.initialize(width, height, parentWidth, parentHeight);
}

@Override
public boolean willChangeBounds() {
    return true;
}
}

如果您有任何问题,挖掘该帖子的陌生人,请随时提问

于 2013-09-20T10:35:54.997 回答