jjzjj

android - 如何在标记下移动 map ?

coder 2023-06-06 原文

假设我们在 map 上有一个居中的标记,当我们用手指移动 map 时,我们可以看到当您离开该区域时该标记将不再显示。那么,尽管我们将 map 移动到任何地方,我们如何制作一个始终保持在 map 中心的标记呢?有一个名为 UBER 的应用程序,他们提供了此功能,您无需拖放标记,只需移动 map ,标记就会保持原位。

这是截图:

如您所见,当我们移动 map 时,绿色标记位于屏幕中央,它保持原位,但在用户停止移动 map 时显示新位置。我们怎么能这样呢?

我有一个代码在您拖放标记时显示地址,如何再次显示地址但这次不是通过拖动、移动 map ?希望你能理解任何想法都会很棒。

public class MainActivity extends AbstractMapActivity implements
    OnNavigationListener, OnInfoWindowClickListener,
    OnMarkerDragListener {
  private static final String STATE_NAV="nav";
  private static final int[] MAP_TYPE_NAMES= { R.string.normal,
    R.string.hybrid, R.string.satellite, R.string.terrain };
  private static final int[] MAP_TYPES= { GoogleMap.MAP_TYPE_NORMAL,
    GoogleMap.MAP_TYPE_HYBRID, GoogleMap.MAP_TYPE_SATELLITE,
    GoogleMap.MAP_TYPE_TERRAIN };
private GoogleMap map=null;
String filterAddress = "";
Marker marker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (readyToGo()) {
        setContentView(R.layout.activity_main);

        SupportMapFragment mapFrag=
            (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);

        mapFrag.setRetainInstance(true);
        initListNav();

        map=mapFrag.getMap();

        if (savedInstanceState == null) {
            CameraUpdate center=
                CameraUpdateFactory.newLatLng(new LatLng(
                        41.003739,
                        28.999572));
            CameraUpdate zoom=CameraUpdateFactory.zoomTo(10);

            map.moveCamera(center);
            map.animateCamera(zoom);

            addMarker(map, 41.003739, 28.999572, R.string.un, R.string.united_nations);

              map.setInfoWindowAdapter(new PopupAdapter(getLayoutInflater()));
              map.setOnInfoWindowClickListener(this);
              map.setOnMarkerDragListener(this);
        }
    }
}

@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
    map.setMapType(MAP_TYPES[itemPosition]);

    return(true);
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);

    savedInstanceState.putInt(STATE_NAV,
            getSupportActionBar().getSelectedNavigationIndex());
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
getSupportActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_NAV));
}

@Override
public void onInfoWindowClick(Marker marker) {
    Toast.makeText(this, marker.getTitle(), Toast.LENGTH_LONG).show();
}

@Override
public void onMarkerDragStart(Marker marker) {
    LatLng position=marker.getPosition();

    Log.d(getClass().getSimpleName(), String.format("Drag from %f:%f",
            position.latitude,
            position.longitude));
}

@Override
public void onMarkerDrag(Marker marker) {
    LatLng position=marker.getPosition();

    Log.d(getClass().getSimpleName(),
            String.format("Dragging to %f:%f", position.latitude,
                    position.longitude));
}

@Override
public void onMarkerDragEnd(Marker marker) {
    LatLng position=marker.getPosition();

    String filterAddress = "";
    Geocoder geoCoder = new Geocoder(
            getBaseContext(), Locale.getDefault());
    try {
        List<Address> addresses = geoCoder.getFromLocation(
                position.latitude, 
                position.longitude, 1);

        if (addresses.size() > 0) {
            for (int index = 0; 
            index < addresses.get(0).getMaxAddressLineIndex(); index++)
                filterAddress += addresses.get(0).getAddressLine(index) + " ";
        }
    }catch (IOException ex) {        
        ex.printStackTrace();
    }catch (Exception e2) {
        // TODO: handle exception
        e2.printStackTrace();
    } 
    Log.d(getClass().getSimpleName(),
            String.format("Dragging to %f:%f", position.latitude,
                    position.longitude));
    TextView myTextView = (TextView) findViewById(R.id.test);

    myTextView.setText("Address is: " + filterAddress);

}

private void initListNav() {
    ArrayList<String> items=new ArrayList<String>();
    ArrayAdapter<String> nav=null;
    ActionBar bar=getSupportActionBar();

    for (int type : MAP_TYPE_NAMES) {
        items.add(getString(type));
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        nav=
            new ArrayAdapter<String>(
                    bar.getThemedContext(),
                    android.R.layout.simple_spinner_item,
                    items);
    }
    else {
        nav=
            new ArrayAdapter<String>(
                    this,
                    android.R.layout.simple_spinner_item,
                    items);
    }

    nav.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    bar.setListNavigationCallbacks(nav, this);
}

private void addMarker(GoogleMap map, double lat, double lon,
        int title, int snippet)

{
    map.addMarker(new MarkerOptions().position(new LatLng(lat, lon))
            .icon(BitmapDescriptorFactory.fromResource(R.drawable.pin))

            .draggable(true));
}
    }

这里是xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/img_header" >

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

<TextView
    android:id="@+id/test"
    android:layout_width="match_parent"
    android:layout_height="90dp"
    android:layout_alignParentRight="true"
    android:text="Address : "
    android:textColor="#FF0000"
    android:textSize="22sp" />
</RelativeLayout>

最佳答案

两个简单的步骤:

第一步

我使用 RelativeLayout 作为 fragment 的父级,其中包含 map 和居中的 ImageView(就像在 uber 或简易出租车应用程序中一样,作为居中的 map 标记):

<!-- Map and ImageView in center for simulating the map marker -->
<RelativeLayout
    android:id="@+id/confirm_address_map_wrapper"
    android:layout_width="match_parent"
    android:layout_height="220dp">

    <fragment
        android:id="@+id/confirm_address_map_fragment"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        />
    <!-- Image View that acts as map marker notice centerInParent-->

     <View
        android:id="@+id/view"
        android:layout_width="1dp"
        android:layout_height="1dp"
        android:layout_centerInParent="true"/>


    <ImageView
        android:id="@+id/confirm_address_map_custom_marker"
        android:layout_width="@dimen/ICON_DEFAULT_SIZE"
        android:layout_height="@dimen/ICON_DEFAULT_SIZE"
        android:layout_above="@+id/view"
        android:layout_centerHorizontal="true"
        android:src="@mipmap/my_map_marker"/>
</RelativeLayout>

第 2 步

onMapReady() 方法在我的 Activity 中我使用 googleMap 实例方法 setOnCameraChangeListener() 让我在使用 map 时收听并根据相机位置的中心获取纬度和经度:

    @Override
    public void onMapReady(GoogleMap googleMap) {

        googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
        @Override
        public void onCameraChange(CameraPosition cameraPosition) {

           Log.i("centerLat",cameraPosition.target.latitude);

           Log.i("centerLong",cameraPosition.target.longitude);
        }
    });

}

更新:
OnCameraChangeListener 已弃用。请使用 OnCameraIdleListener:
[来源:https://stackoverflow.com/a/38732283/421467]

关于android - 如何在标记下移动 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19346206/

有关android - 如何在标记下移动 map ?的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  5. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  6. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  7. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  8. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  9. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  10. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

随机推荐