创建叠加ImageView动画谷歌地图

Zul*_*utt 15 android google-maps imageview android-animation google-maps-android-api-2

我正在尝试使我的叠加图像执行以下操作:

  • onMap/onDrag的地图,在地图中间显示一个恒定的图像,这是一个图钉
  • onTouchUp,将标记图像更改为加载标记,一旦数据加载完成,将图像加载到带有文本的新图像.

这是一个非常类似于我的问题的解决方案:

animatedMarker

到目前为止我做了什么?

  • 在我的谷歌地图中间放置了一个图像视图,并获得了使用mMap.getCameraPosition().target 该图像的图像,使用它可以得到大约中间位置坐标 setOnCameraChanged,我知道已经弃用了,还有更好的解决方案吗?
  • 剩下的部分我无法弄清楚,虽然我已经阅读了几个SO问题,声称他们已经实现了将framelayout包装在谷歌地图的片段上,并在其上应用onTouch,但也无法找到对它的正确答案.

所有这一切发生的我的xml片段如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragments.MovableMapFragment">

    <fragment
        android:id="@+id/map_frag_fmm"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/tablayout_global_tabs"
        android:layout_alignParentTop="true" />
<! -- long xml ahead -->
Run Code Online (Sandbox Code Playgroud)

有人知道如何实现这种行为吗?

Fed*_*nov 7

Android自定义Pin

最好的解决方案是使用RxJava/RxAndroid并使用它执行后台任务,但是我不能在没有看到你的代码的情况下使用rx发布解决方案,并且已经有来自@ user27799的示例@Manas Chaudhari提供了对逻辑的一个很好的解释(在下面).

//bunch of imports
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback
{

  private GoogleMap mGoogleMap;
  private FrameLayout frameLayout, circleFrameLayout;
  private ProgressBar progress;
  private TextView textView;
  private int circleRadius;
  private boolean isMoving = false;
  private SupportMapFragment mapFragment;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    initViews();
  }

  private void initViews() {

    frameLayout = (FrameLayout) findViewById(R.id.map_container);

    circleFrameLayout = (FrameLayout) frameLayout.findViewById(R.id.pin_view_circle);
    textView = (TextView) circleFrameLayout.findViewById(R.id.textView);
    progress = (ProgressBar) circleFrameLayout.findViewById(R.id.profile_loader);

    mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

}

  private void moveMapCamera() {
    if (mGoogleMap == null) {
        return;
    }

    CameraUpdate center = CameraUpdateFactory
            .newLatLng(new LatLng(40.76793169992044, -73.98180484771729));
    CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);

    mGoogleMap.moveCamera(center);
    mGoogleMap.animateCamera(zoom);
}

  @Override
  public void onMapReady(GoogleMap googleMap) {
    mGoogleMap = googleMap;

    mGoogleMap.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() {

        /* User starts moving map - change your pin's image here 
        */
        @Override
        public void onCameraMoveStarted(int i) {
            isMoving = true;
            textView.setVisibility(View.GONE);
            progress.setVisibility(View.GONE);
            Drawable mDrawable;
            if (Build.VERSION.SDK_INT >= 21)
                mDrawable = getApplicationContext().getResources().getDrawable(R.drawable.circle_background_moving, null);
            else
                mDrawable = getApplicationContext().getResources().getDrawable(R.drawable.circle_background_moving);

            circleFrameLayout.setBackground(mDrawable);
            resizeLayout(false);
        }
    });

    /*User stoped moving map -> retrieve location and do your background task */
    mGoogleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
        @Override
        public void onCameraIdle() {

            isMoving = false;
            textView.setVisibility(View.INVISIBLE);
            progress.setVisibility(View.VISIBLE);
            resizeLayout(true);

            /* this is just an example that simulates data loading
               you shoud substitute it with your logic
            */
            new Handler().postDelayed(new Runnable() {
                public void run() {

                    Drawable mDrawable;
                    if (Build.VERSION.SDK_INT >= 21)
                        mDrawable = getApplicationContext().getResources().getDrawable(R.drawable.circle_background, null);
                    else
                        mDrawable = getApplicationContext().getResources().getDrawable(R.drawable.circle_background);

                    if (!isMoving) {
                        circleFrameLayout.setBackground(mDrawable);
                        textView.setVisibility(View.VISIBLE);
                        progress.setVisibility(View.GONE);
                    }
                }
            }, 1500);
        }
    });

    MapsInitializer.initialize(this);
    moveMapCamera();
  }

  //resing circle pin
  private void resizeLayout(boolean backToNormalSize){
    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) circleFrameLayout.getLayoutParams();

    ViewTreeObserver vto = circleFrameLayout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            circleFrameLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            circleRadius = circleFrameLayout.getMeasuredWidth();
        }
    });

    if (backToNormalSize) {
        params.width = WRAP_CONTENT;
        params.height = WRAP_CONTENT;
        params.topMargin = 0;

    } else {
        params.topMargin = (int) (circleRadius * 0.3);
        params.height = circleRadius - circleRadius / 3;
        params.width = circleRadius - circleRadius / 3;
    }

    circleFrameLayout.setLayoutParams(params);
  }

}
Run Code Online (Sandbox Code Playgroud)

布局文件,其中图钉位于屏幕中央:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/map_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

<fragment xmlns:tools="http://schemas.android.com/tools"
          android:id="@+id/map"
          android:name="com.google.android.gms.maps.SupportMapFragment"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:context="com.example.mapstest.MapsActivity" />

<FrameLayout
    android:id="@+id/pin_view_line"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginTop="@dimen/line_top_margin"
    android:background="@drawable/line_background"/>

<FrameLayout
    android:id="@+id/pin_view_circle"
    android:layout_gravity="center"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/circle_background">

    <TextView
        android:id="@+id/textView"
        android:layout_margin="@dimen/inner_circle_margin"
        android:layout_width="@dimen/inner_circle_radius"
        android:layout_height="@dimen/inner_circle_radius"
        android:layout_gravity="top|center_horizontal"
        android:gravity="center"
        android:text="12 min"
        android:textSize="@dimen/text_size"
        android:textColor="@android:color/white"/>

    <ProgressBar
        android:id="@+id/profile_loader"
        android:layout_margin="@dimen/inner_circle_margin"
        android:layout_width="@dimen/inner_circle_radius"
        android:layout_height="@dimen/inner_circle_radius"
        android:indeterminate="true"
        android:layout_gravity="top|center_horizontal"
        android:visibility="gone"
        android:contentDescription="@null"/>

</FrameLayout>
Run Code Online (Sandbox Code Playgroud)

不移动时圈出背景:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="oval">    
<solid android:color="@android:color/holo_green_dark"/>
<stroke
    android:width="@dimen/stroke_width"
    android:color="@android:color/black"/>
<size
    android:width="@dimen/circle_radius"
    android:height="@dimen/circle_radius"/>
</shape>
Run Code Online (Sandbox Code Playgroud)

地图移动时的圆形背景:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="oval">    
<solid android:color="@android:color/black"/>
<size
    android:width="@dimen/circle_radius"
    android:height="@dimen/circle_radius"/>
</shape>
Run Code Online (Sandbox Code Playgroud)

线背景文件:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">    
<solid android:color="@android:color/black"/>
<size
    android:width="@dimen/line_width"
    android:height="@dimen/line_height"/>
</shape>
Run Code Online (Sandbox Code Playgroud)

外形尺寸:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <dimen name="circle_radius">48dp</dimen>
  <dimen name="line_width">4dp</dimen>
  <dimen name="line_height">40dp</dimen>
  <dimen name="stroke_width">4dp</dimen>
  <dimen name="text_size">10sp</dimen>
  <dimen name="inner_circle_radius">40dp</dimen>
  <dimen name="inner_circle_margin">4dp</dimen>
  <dimen name="line_top_margin">20dp</dimen>
</resources>
Run Code Online (Sandbox Code Playgroud)

我希望它可以帮到你,但是如果你有任何问题可以随意提出,或者如果你看到你要改进的领域 - 编辑我的解决方案.

干杯.


Nic*_*nko 5

将布局放在FrameLayout中并在Map上绘制图片.当GoogleMap准备就绪时(我的代码使用RxJava):

Observable.<Void>create(subscriber -> {
        mMap.setOnCameraIdleListener(() -> subscriber.onNext(null));
    })
            .debounce(1, TimeUnit.SECONDS)
            .subscribeOn(AndroidSchedulers.mainThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(aVoid -> {
                LatLng newPos = mMap.getProjection().fromScreenLocation(new Point(mBinding.googleMap.getWidth() / 2, mBinding.googleMap.getHeight() / 2));

                makeServerRequest(newPos);
            });
Run Code Online (Sandbox Code Playgroud)