创建叠加ImageView动画Google Map [英] Create Overlay ImageView Animation Google Map

查看:220
本文介绍了创建叠加ImageView动画Google Map的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我的覆盖图像做以下事情:




  • onClick / onDrag地图,在地图的中间
    这是一个pin

  • onTouchUp,将标记图像更改为加载标记,并且一次数据
    加载完成将图像加载到带有文本的新图像。 li>


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



我到目前为止做了什么?




  • 放置在我的谷歌地图在中间imageview,并获得
    loacation该图像使用 mMap.getCameraPosition()。目标
    给出大约中间位置坐标使用
    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>

<片段
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/>
<! - 长xml提前 - >

有人知道如何达到这种行为吗?

解决方案



最好的解决方案是使用RxJava / RxAndroid并使用它进行后台任务,但是我不能在没有看到代码的情况下使用rx发布解决方案,并且已经有@ user27799的示例,@Manas Chaudhari也提供了有关逻辑(在下面)。

  //一堆进口
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT ;

公共类MapsActivity扩展AppCompatActivity实现OnMapReadyCallback
{

私有GoogleMap mGoogleMap;
private FrameLayout frameLayout,circleFrameLayout;
私人ProgressBar进度;
私人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);
$ b $ mapFragment =(SupportMapFragment)getSupportFragmentManager()。findFragmentById(R.id.map);
mapFragment.getMapAsync(this);


$ b 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(新的GoogleMap.OnCameraMoveStartedListener(){

/ *用户开始移动地图 - 在这里更改您的图钉图像
* /
@覆盖
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);
}
});

/ *用户停用的移动地图 - >检索位置并执行后台任务* /
mGoogleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener(){
@Override
public void onCameraIdle(){

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

/ *这只是一个模拟数据加载的例子
你应该用你的逻辑代替它
* /
new Handler()。postDelayed(new Runnable(){
public void run(){

可绘制mDrawable;
if(Build.VERSION.SDK_INT> = 21)
mDrawable = getApplicationContext()。getResources()。getDrawable(R.drawable.circle_background,null) ;
else
mDrawable = getApplicationContext()。getResources()。get绘制对象(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);
}

}

布局文件:

 <?xml version =1.0encoding =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 =@
android:layout_gravity =@ dimen / inner_circle_radius
android:layout_gravity =top | center_horizo​​ntal
android:gravity =center 12分钟
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 =@
android:layout_gravity =@ dimen / inner_circle_radius
android:visibility =true
android:layout_gravity =top | center_horizo​​ntal gone
android:contentDescription =@ null/>

< / FrameLayout>





 <?xml version =1.0encoding =utf-8?> 
< shape xmlns:android =http://schemas.android.com/apk/res/android
android:shape =oval>
< solid android:color =@ android:color / holo_green_dark/>
android:width =@ dimen / stroke_width
android:color =@ android:color / black/>
< size
android:width =@ dimen / circle_radius
android:height =@ dimen / circle_radius/>
< / shape>

地图移动时圈出背景:

 <?xml version =1.0encoding =utf-8?> 
< shape xmlns:android =http://schemas.android.com/apk/res/android
android:shape =oval>
< size
android:width =@ dimen / circle_radius
android:height =@ dimen / circle_radius/>
< / shape>

行背景文件:

 <?xml version =1.0encoding =utf-8?> 
< shape xmlns:android =http://schemas.android.com/apk/res/android
android:shape =rectangle>
< size
android:width =@ dimen / line_width
android:height =@ dimen / line_height/>
< / shape>

维度:

 <?xml version =1.0encoding =utf-8?> 
<资源>
< 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>
< /资源>

我希望它对您有所帮助,但如果您有任何问题,请随时询问或看到区域你会改进 - 编辑我的解决方案。



干杯。


I am trying to make my overlay image to do following things:

  • onClick / onDrag of map , show a constant image at the middle of map which is a pin
  • onTouchUp , change marker image to Loading marker and once data loading complete change loading image to new image with text.

Here is a pretty similar solution to my problem:

What i have done so far ?

  • Placed an imageview over my google map in the middle , and got loacation of that imageView using mMap.getCameraPosition().target which gives approx middle position coordinates using setOnCameraChanged , i know that's deprecated, well have a better solution?.
  • Rest of the part i can't figure out , though i have read several SO questions claiming they have implemented it wrapping framelayout over fragment of google map, and applying onTouch on that, but cannot find an authentic answer to that one too.

my xml of fragment where all this is happening looks like this :

<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 -->

Someone know how to achieve this kind of behavior ?

解决方案

The best solution would be to use RxJava/RxAndroid and do background tasks with it, but I can't post a solution using rx without seeing your code and there's already an example from @user27799 also @Manas Chaudhari provided a great explanation of the logic (down below).

//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);
  }

}

Layout file with pin in the center of the screen:

<?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>

Circle background when not moving:

<?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>

Circle background when map is moving:

<?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>

Line background file:

<?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>

Dimensions:

<?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>

I hope it helps you, but if you have any questions feel free to ask or if you see areas that you'd improve - edit my solution.

Cheers.

这篇关于创建叠加ImageView动画Google Map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆