【问题标题】:Using Umano/SlidingUpPanel With False Overlay Issue使用带有错误叠加问题的 Umano/SlidingUpPanel
【发布时间】:2015-12-08 23:39:40
【问题描述】:

我在我的应用程序中使用 Umano/SlidingUpPanel 库,其中地图是主要内容。一个面板在地图上向上滑动。我将 overlay 属性设置为 false,因为我希望 在面板向上滑动时向上移动(如 WhatsApp 聊天窗口)

我面临的问题是:我的主要内容,即地图正在动摇或可能 每次面板上下滑动时都会重新调整大小。

请查看链接以进一步了解问题:

https://www.dropbox.com/s/imjlso12xarzf57/Video%2001-12-15%2C%2012%2049%2058%20PM.mov?dl=0

面板上下滑动时地图抖动。

activity_main:

<com.sothree.slidinguppanel.SlidingUpPanelLayout
    xmlns:sothree="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/sliding_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="bottom"
    sothree:umanoFadeColor="@android:color/transparent"
    sothree:umanoOverlay = "false"
    sothree:umanoDragView="@+id/dragView">


    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        class="com.google.android.gms.maps.SupportMapFragment"/>

</FrameLayout>
    <include layout="@layout/sliding_fragment_layout"
        android:background="#ffffff"
        android:id="@+id/dragView"/>
    <!--<FrameLayout-->
            <!--android:id="@+id/list_fragment_container"-->
            <!--android:layout_width="match_parent"-->
            <!--android:layout_height="match_parent"/>-->

</com.sothree.slidinguppanel.SlidingUpPanelLayout>   

Sliding_fragment_layout:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
    android:id="@+id/verified"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="60dp"
    android:paddingLeft="10dp"
    android:background="#FFFF"
    android:paddingRight="10dp"
    android:paddingTop="10dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
                <!--android:descendantFocusability="beforeDescendants"-->
                <!--android:focusableInTouchMode="true"-->

                <TableRow
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="1dp"
                    android:weightSum="1">

                        <TextView
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:id="@+id/employer_textView_id"
                            android:layout_weight=".4"
                            android:padding="5dp"
                            android:textSize="15sp"
                            android:textColor="@android:color/black"/>




                </TableRow>

                <TableRow
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="0.5dp"
                    android:weightSum="1">

                        <TextView
                            android:layout_width="100dp"
                            android:layout_height="wrap_content"
                            android:padding="2dp"
                            android:textSize="15sp"
                            android:layout_weight="1"
                            android:gravity="fill_horizontal"
                            android:id="@+id/address_textView_id"
                            android:textColor="@android:color/black"/>

                </TableRow>
                <View
                    android:layout_width="fill_parent"
                    android:layout_height="1dp"
                    android:background="#c0c0c0"/>

               <TextView
                   android:layout_width="match_parent"
                   android:layout_height="match_parent"
                   android:text="Hello"
                   android:id="@+id/text"/>
        </TableLayout>

MainActivity.java

public class MainActivity extends FragmentActivity implements LocationListener {

    private static final String LIST_FRAGMENT_TAG = "list_fragment";
    private static final String TAG = "DemoActivity";

    GoogleMap googleMap;
    double currentLat , currentLon;
    LocationManager locationManager;
    Location mlocation;
    double latitude;
    double longitude;
    LatLng latLng,points;
    Boolean flag = false;
    String mLastUpdateTime;
    CameraPosition INIT;
    private SlidingUpPanelLayout mLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (!isGooglePlayServiceAvailable()) {
            finish();
        }
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);


        googleMap = mapFragment.getMap();
        googleMap.setMyLocationEnabled(true);
        googleMap.getUiSettings().setCompassEnabled(false);

        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);


        Criteria criteria = new Criteria();
        String bestProvider = locationManager.getBestProvider(criteria, true);
        mlocation = locationManager.getLastKnownLocation(bestProvider);
        if (mlocation != null) {
            onLocationChanged(mlocation);
        }
        locationManager.requestLocationUpdates(bestProvider, 20000, 0, this);

        /*SlidingPanelUpLayout*/
        mLayout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
//        mLayout.setAnchorPoint(0.3f);
        mLayout.setPanelState(SlidingUpPanelLayout.PanelState.HIDDEN);
        mLayout.setPanelHeight(500);
//        mLayout.setParallaxOffset(10);
        mLayout.setPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() {
            @Override
            public void onPanelSlide(View panel, float slideOffset) {
                Log.i(TAG, "onPanelSlide, offset " + slideOffset);
                googleMap.getUiSettings().setAllGesturesEnabled(true);
            }

            @Override
            public void onPanelExpanded(View panel) {
                Log.i(TAG, "onPanelExpanded");
                googleMap.getUiSettings().setAllGesturesEnabled(false);

            }

            @Override
            public void onPanelCollapsed(View panel) {
                flag=true;
                Log.i(TAG, "onPanelCollapsed");
                googleMap.getUiSettings().setAllGesturesEnabled(false);

            }

            @Override
            public void onPanelAnchored(View panel) {
                Log.i(TAG, "onPanelAnchored");

            }

            @Override
            public void onPanelHidden(View panel) {
                flag=false;
                Log.i(TAG, "onPanelHidden");
            }
        });
    }

    public Boolean isGooglePlayServiceAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }

    }


    @Override
    public void onLocationChanged(Location location) {
        mlocation = location;
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        latLng = new LatLng(latitude, longitude);
        long atTime = mlocation.getTime();
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date(atTime));

//        mapView.setCenterCoordinate(latLng1);

        MarkerOptions options = new MarkerOptions();
        options.position(latLng).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
//        Marker marker = googleMap.addMarker(options);
        googleMap.addMarker(options.title(getAdress()));
        googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//        View view = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.custom_marker_layout, null);

        INIT =
                new CameraPosition.Builder()
                        .target(latLng)
                        .zoom(17.5F)
                        .bearing(300F) // orientation
                        .tilt(50F) // viewing angle
                        .build();
        googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(INIT));
        googleMap.getUiSettings().setCompassEnabled(false);
//
//        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 13));
        int Radius = 100;
        googleMap.addMarker(new MarkerOptions()
                .position(latLng)
//                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE))
                .title(getAdress())
                .snippet("Radius: " + Radius))
                .showInfoWindow();

        googleMap.addMarker(new MarkerOptions().position(new LatLng(28.7494720, 77.0565330)));

        googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {

            @Override
            public boolean onMarkerClick(Marker marker) {

//                flag = true;
                Log.i("Marker","Click");
                points = new LatLng(marker.getPosition().latitude,marker.getPosition().longitude);
                if(flag==false){
                if(mLayout!=null){

                        Log.i("Marker", "collapsed");
                    mLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
                    animateLatLngZoom(points, 0, -10, 10);

                }}else{
                    Log.i("Marker","Hidden");                        mLayout.setPanelState(SlidingUpPanelLayout.PanelState.HIDDEN);
                }


                return true;
            }

        });


//        //Instantiates a new CircleOptions object +  center/radius 28.6328° N, 77.2197°
//        CircleOptions circleOptions = new CircleOptions()
//                .center(new LatLng(latitude, longitude))
//                .radius(Radius)
//                .fillColor(0x40ff0000)
//                .strokeColor(Color.GREEN)
//                .strokeWidth(2);
//
//// Get back the mutable Circle
//        Circle circle = googleMap.addCircle(circleOptions);
//        Circle circle1 = googleMap.addCircle(new CircleOptions().center(new LatLng(28.633908, 77.221094))
//                .radius(100)
//                .fillColor(0x40ff0000)
//                .strokeColor(Color.BLUE)
//                .strokeWidth(5));
//// more operations on the circle...
//        // =
//
//
//        googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));

    }

    private void animateLatLngZoom(LatLng latlng, int reqZoom, int offsetX, int offsetY) {
        /*calculate the offset's center in the required zoom from original's offset, and then animate the map's camera.
        For this, first move the map's camera to the desired zoom, calculate the offset for that zoom level, and then restore
        the original zoom.After calculating the new center we can make the animation with CameraUpdateFactory.newLatLngZoom.*/



        // Save current zoom
//      float originalZoom = googleMap.getCameraPosition().zoom;

        // Move temporarily camera zoom
//      googleMap.moveCamera(CameraUpdateFactory.zoomTo(reqZoom));

        Point pointInScreen = googleMap.getProjection().toScreenLocation(latlng);

        Point newPoint = new Point();
        newPoint.x = pointInScreen.x + offsetX;
        newPoint.y = pointInScreen.y + offsetY;

        LatLng newCenterLatLng = googleMap.getProjection().fromScreenLocation(newPoint);

        // Restore original zoom
//      googleMap.moveCamera(CameraUpdateFactory.zoomTo(originalZoom));

        // Animate a camera with new latlng center and required zoom.
//      googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(newCenterLatLng, reqZoom));
        googleMap.animateCamera(CameraUpdateFactory.newLatLng(newCenterLatLng));

    }

    public String getAdress() {

        Geocoder geocoder;
        String result = null;
        List<Address> addresses;
        geocoder = new Geocoder(this, Locale.getDefault());
        try {
            addresses = geocoder.getFromLocation(latitude, longitude, 1);

            if (addresses != null && addresses.size() > 0) {
                Address address = addresses.get(0);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                    sb.append(address.getAddressLine(i)).append("\n");
                }
//                sb.append(address.getLocality()).append("\n");
//                sb.append(address.getPostalCode()).append("\n");
                sb.append(address.getCountryName().toUpperCase());
                result = sb.toString();
            }
        } catch (IOException e) {
            Log.e("Loaction Address", "Unable connect to Geocoder", e);
        }
        return result;

    }


    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_show_list) {
//            toggleList();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

请帮我解决。谢谢

【问题讨论】:

    标签: android android-activity google-maps-android-api-2 android-maps-v2


    【解决方案1】:

    我不确定这个问题是否可以直接解决。但是我可以想象两种可能的解决方法:

    1. 尝试在lite mode 中显示地图。您也可以尝试使用 2 个地图:第一个在默认模式下工作,第二个在 lite 模式下工作,然后在需要显示 sligin up 面板时在它们之间切换。
    2. 您可以将PanelSlideListener 附加到SligingUpPanel,将overlay 属性设置为true,并在PanelSlideListener.onPanelSlide 中使用moveCamera/animateCamera 方法组合对地图的Camera 对象应用更改使用setPadding 方法(也可以移动地图控件)。这肯定会解决问题,因为地图视图不会调整大小,而是您将手动控制Camera 对象。但是,这种方法需要做更多的工作。

    更新 Here's 我建议的一个例子。希望我以正确的方式理解您的问题。您只需要创建一个空项目,在其中添加提供的Activity 代码、它的布局和必要的依赖项+ 创建具有必要权限的适当AndroidManifest

    【讨论】:

    • 所以,overlay 属性设置为 true 的问题是:菜单出现在 Map 上。我希望它向上移动主要内容而不会晃动或调整地图大小。
    • 阅读我的第二点:它会出现在地图上,但您可以使用 setPadding/moveCamera/animateCamera 方法组合手动移动地图控件/地图相机。地图视图基于对调整大小敏感的 SurfaceView/TextureView。所以我的观点是你不能使用 overlay=false 但可以解决你的问题。
    • 我没有得到,这样做的方法。你能按照你的方式用一些代码解释我或在上面的代码中添加行吗?请。
    • 我过去解决过类似的问题。 stackoverflow.com/questions/20395345/…
    • 不,我的问题不是那个。
    【解决方案2】:

    您可以使用android-transition 库将Y 平移应用于地图视图:

    分级:

    compile 'com.github.kaichunlin.transition:core:0.9.4'
    compile 'com.github.kaichunlin.transition:slidinguppanel:0.9.1'
    

    代码:

    SlidingUpPanelLayoutAdapter adapter=new SlidingUpPanelLayoutAdapter();     
    mLayout.setPanelSlideListener(adapter);         
    adapter.addTransition(ViewTransitionBuilder.transit(findViewById(R.id.map)).interpolator(new LinearInterpolator()).translationY(-250));
    

    注意,为了使这个工作,您必须将面板状态从隐藏更改为折叠,并将面板高度设置为 0:

    mLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
    mLayout.setPanelHeight(0);
    

    将面板状态设置为 EXPANDED 而不是 COLLAPSED:

    mLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
    

    并且还在sliding_fragment_layout.xml中设置TableLayout的layout_height为500px,(应该改成使用dp,但是使用px就足够了)

    效果演示:https://www.dropbox.com/s/gcozdrol8ed8zcc/test.mp4?dl=0

    【讨论】:

    【解决方案3】:

    我认为最好的解决方案是使用视差效果。

    您应该设置 umanoOverlay="true" 以确保地图保持其大小。然后,为向上滑动的面板提供锚点(例如:umanoAnchorPoint="0.60")和视差效果(例如:umanoParalaxOffset="250dp")。单击标记时,将相机动画到该标记以确保它位于地图的中间。你也应该给 umanoPanelHeight="0dp" 因为你想通过点击标记来显示面板,如果我知道的话。

    所以会是这样的

        sothree:umanoAnchorPoint="0.60"
        sothree:umanoDragView="@+id/dragView"
        sothree:umanoParalaxOffset="250dp"
        sothree:umanoPanelHeight="0dp"
        sothree:umanoShadowHeight="0dp"
        sothree:umanoFadeColor="@android:color/transparent"
        sothree:umanoOverlay="true"
    

    在您的标记点击监听器中

    @Override
    public boolean onMarkerClick(Marker marker) {
    
        points = new LatLng(marker.getPosition().latitude,marker.getPosition().longitude);
    
        // if panel is collapsed
        if (mLayout.getPanelState().equals(
                SlidingUpPanelLayout.PanelState.COLLAPSED)) {
                // then show the panel content
                mLayout.setPanelState(SlidingUpPanelLayout.PanelState.ANCHORED);
                // animate your camera somehow
                animateLatLngZoom(points, 0, -10, 10);
            } else { // if panel is anchored or expanded
                // collapse it
                mLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
            }
    
        return true;
    }
    

    【讨论】:

    • 我做了更改,但对我不起作用。它覆盖了地图上的滑动面板,而不是在地图上向上滑动面板。就像我在视频中展示的那样。
    【解决方案4】:

    我认为使用sothree:umanoOverlay="false" 消除这种不想要的效果确实会有问题,因为将该选项设置为 false 需要 Android 在每次更改表格高度时布局您的地图。

    因此,您可能的解决方案是让您的滑动面板被覆盖并跟踪它的上下移动,相应地调整您的地图平移。

    这是一个简单的例子:

    @Override
    public void onPanelSlide(View panel, float slidingOffset) {
        adjustViews(slidingOffset, false);
    }
    
    @Override
    public void onPanelCollapsed(View panel) {
    }
    
    @Override
    public void onPanelExpanded(View panel) {
    }
    
    @Override
    public void onPanelAnchored(View panel) {
        adjustViews(mSlidingPanelLayout.getAnchorPoint(), true);
    }
    
    @Override
    public void onPanelHidden(View view) {
    }
    
    private void adjustViews(final float slideOffset, boolean anchor) {
    
        float height = mSlidingPanelLayout.getHeight();
        float panelHeight = mSlidingPanelLayout.getPanelHeight();   
    
        mMapFragment.setMapTranslationY(-(int) ((height - panelHeight) * slideOffset) - mSlidingPanelLayout.getCurrentParalaxOffset());
    }
    

    我想你还需要做一些其他的事情:实现 setMapTranslationY 并在旋转期间保存/恢复状态。

    【讨论】:

      猜你喜欢
      • 2014-05-02
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多