12

मैं निम्नलिखित काम करने की मेरी ओवरले छवि बनाने के लिए कोशिश कर रहा हूँ:ओवरले imageView एनीमेशन गूगल मानचित्र बनाएं

  • onClick/नक्शे के onDrag, नक्शे के बीच जो एक पिन
  • है पर एक स्थिर छवि दिखाने
  • ऑन टचअप, मार्कर लोड करने के लिए मार्कर छवि बदलें और एक बार डेटा टेक्स्ट के साथ नई छवि में पूर्ण परिवर्तन लोडिंग छवि लोड हो रहा है।

    animatedMarker

    क्या मैं अब तक क्या किया है:

यहाँ मेरी समस्या के लिए एक सुंदर समान समाधान है?

  • बीच में मेरी गूगल मानचित्र पर एक imageView रखा, और कहा कि imageView mMap.getCameraPosition().target का उपयोग करने का loacation मिला जो देता है लगभग बीच स्थिति का उपयोग कर setOnCameraChanged, मुझे पता है कि पदावनत है निर्देशांक, अच्छी तरह से एक बेहतर समाधान है ?.
  • शेष भाग मैं समझ नहीं पा रहा हूं, हालांकि मैंने कई एसओ सवालों को पढ़ा है कि उन्होंने इसे Google मानचित्र के टुकड़े पर फ़्रेमेलआउट को लपेटने के लिए लागू किया है, और उस पर टच लगाने पर लागू किया है, लेकिन उस पर भी एक प्रामाणिक उत्तर नहीं मिल रहा है ।

मेरी टुकड़ा जहां यह सब क्या हो रहा है की एक्सएमएल इस तरह दिखता है:

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

किसी जानते हैं कि कैसे इस तरह का व्यवहार प्राप्त करने के लिए?

+0

मुझे लगता है कि आपको (x, y) निर्देशांक से कनवर्ट करना चाहिए, जिसे आप अपनी छवि दृश्य से प्राप्त कर सकते हैं (या केवल नक्शा कंटेनर का केंद्र, क्योंकि आपके मामले में छवि ठीक हो गई है) लेट/एलएनजी समन्वय में। [इस पोस्ट] की जांच करें (http://stackoverflow.com/questions/25219346/how-to-convert-from-x-y- स्क्रीन-coordinates-to-latlng-google-maps) – Beloo

उत्तर

5

Android Custom Pin

सबसे अच्छा समाधान RxJava/RxAndroid का उपयोग करें और इसके साथ पृष्ठभूमि कार्य करने के लिए होगा, लेकिन मैं एक समाधान पोस्ट नहीं कर सकते rx का उपयोग कर अपना कोड देखे बिना और @ user27799 से पहले से ही एक उदाहरण है @ मनस चौधरी ने तर्क (नीचे नीचे) का एक बड़ा स्पष्टीकरण प्रदान किया है।स्क्रीन के बीच में पिन के साथ

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

} 

लेआउट फ़ाइल:

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

सर्किल पृष्ठभूमि जब नहीं चलती:

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

सर्किल पृष्ठभूमि जब नक्शा बढ़ रहा है:

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

रेखा पृष्ठभूमि फ़ाइल:

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

आयाम:

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

मुझे आशा है कि यह आप में मदद करता है, लेकिन अगर आपके पास कोई प्रश्न पूछने के लिए स्वतंत्र महसूस हो रहा है या आप में सुधार चाहते हैं कि आप क्षेत्रों को देखने अगर - मेरा समाधान संपादित करें।

चीयर्स।

1

लेआउट

चिह्न नक्शे पर विशिष्ट निर्देशांक पर तैनात किया जाना लिए होती हैं। इस प्रकार, जब आप मानचित्र बदलते हैं तो वे आगे बढ़ते हैं।

चूंकि आपका पिन हमेशा मानचित्र के मध्य में होता है, यह Marker का उपयोग करके इसे बनाने के लिए उपयुक्त नहीं है। इसके बजाय, आप नक्शा कंटेनर के केंद्र में मानचित्र के टुकड़े के बाहर रख सकते हैं। तो अपने एक्सएमएल इस प्रकार दिखना चाहिए:

<RelativeLayout> 
    <fragment 
    android:id="@+id/map_fragment" /> 

    <RelativeLayout 
    android:id="@+id/pin_view" 
    android:centerInParent="true" /> 
</RelativeLayout> 

आप अपने आवश्यकता के अनुसार एनिमेशन लागू करने के लिए pin_view करने के लिए बच्चों को जोड़ सकते हैं।

पिन स्टेट्स

आप द्वारा प्रदान की gif के आधार पर, वहाँ पिन के लिए तीन राज्यों हो सकता है।

  • खाली
  • लोड हो रहा है
  • लोडेड

श्रोताओं

आप इन श्रोताओं की स्थापना करके एनिमेशन को गति प्रदान कर सकते हैं:

  • setOnCameraMoveStartedListener
    • पिछला मूल्य अमान्य होने की आवश्यकता है। Empty
    • को बदलें पिन के राज्य रद्द किसी भी चल रहे अनुरोधों
  • setOnCameraIdleListener
    • प्राप्त एक नेटवर्क कॉल 'लोड हो रहा है'
    • ट्रिगर करने के लिए map.getCameraPosition()
    • पिन के बदले राज्य का उपयोग डेटा प्राप्त करने का समन्वय करता है। कॉलबैक में
      • पिन के बदले राज्य के लिए 'लोड' और प्रदर्शित मूल्य ध्यान दें कि कॉलबैक निष्पादित नहीं किया जाएगा, उपयोगकर्ता चाल से पहले एपीआई पूरा करता है, के रूप में हम उपयोगकर्ता चाल के रूप में जैसे ही अनुरोध रद्द हो जाएगा। तो, इस परिदृश्य भी
4

का ध्यान रखा जाना होगा रखो आप FrameLayout में लेआउट और मानचित्र से अधिक चित्र बनाने। जब 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); 
      }); 
संबंधित मुद्दे