ক্যামেরাআপডেটফ্যাক্টরি সহ মুভকামেরা


96

আমি নতুন অ্যান্ড্রয়েড গুগল ম্যাপস এপিআই ব্যবহার করছি ।

আমি একটি ক্রিয়াকলাপ তৈরি করি যা মানচিত্রের অন্তর্ভুক্ত। ক্রিয়াকলাপে onResumeআমি চিহ্নিতকারীগুলিকে গুগলম্যাপ অবজেক্টে সেট করি এবং তারপরে মানচিত্রের জন্য একটি বাউন্ডিং বাক্স সংজ্ঞায়িত করে যার মধ্যে সমস্ত মার্কার থাকে।

এটি নিম্নলিখিত সিউডো কোডটি ব্যবহার করছে:

LatLngBounds.Builder builder = new LatLngBounds.Builder();
while(data) {
   LatLng latlng = getPosition();
   builder.include(latlng);
}
CameraUpdate cameraUpdate = CameraUpdateFactory
   .newLatLngBounds(builder.build(), 10);
map.moveCamera(cameraUpdate);

কলটি map.moveCamera()আমার অ্যাপ্লিকেশনটিকে নিম্নোক্ত স্ট্যাকের সাথে ক্রাশ করে:

Caused by: java.lang.IllegalStateException: 
    Map size should not be 0. Most likely, layout has not yet 

    at maps.am.r.b(Unknown Source)
    at maps.y.q.a(Unknown Source)
    at maps.y.au.a(Unknown Source)
    at maps.y.ae.moveCamera(Unknown Source)
    at com.google.android.gms.maps.internal.IGoogleMapDelegate$Stub
        .onTransact(IGoogleMapDelegate.java:83)
    at android.os.Binder.transact(Binder.java:310)
    at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a
        .moveCamera(Unknown Source)
    at com.google.android.gms.maps.GoogleMap.moveCamera(Unknown Source)
    at ShowMapActivity.drawMapMarkers(ShowMapActivity.java:91)
    at ShowMapActivity.onResume(ShowMapActivity.java:58)
    at android.app.Instrumentation
        .callActivityOnResume(Instrumentation.java:1185)
    at android.app.Activity.performResume(Activity.java:5182)
    at android.app.ActivityThread
        .performResumeActivity(ActivityThread.java:2732)

যদি - newLatLngBounds()কারখানার পদ্ধতির পরিবর্তে আমি newLatLngZoom()পদ্ধতিটি ব্যবহার করি তবে একই ফাঁদটি ঘটে না।

কি onResumeসবচেয়ে ভাল জায়গা GoogleMap বস্তুর সম্মুখের চিহ্নিতকারী আঁকা অথবা আমি চিহ্নিতকারী অঙ্কন করা উচিত এবং অন্য কোথাও ক্যামেরা অবস্থান সেটিং?

উত্তর:


133

আপনি সহজ ব্যবহার করতে পারেন newLatLngBounds পদ্ধতি OnCameraChangeListener । সমস্ত নিখুঁতভাবে কাজ করবে এবং আপনার পর্দার আকার গণনা করার দরকার নেই। এই ইভেন্টটি মানচিত্রের আকার গণনার পরে ঘটে (যেমন আমি বুঝতে পারি)।

উদাহরণ:

map.setOnCameraChangeListener(new OnCameraChangeListener() {

    @Override
    public void onCameraChange(CameraPosition arg0) {
        // Move camera.
        map.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 10));
        // Remove listener to prevent position reset on camera move.
        map.setOnCameraChangeListener(null);
    }
});

4
এটি কাজ করে কারণ মানচিত্রের লেআউটটি চলে যাওয়ার পরে সেটঅন ক্যামেরাচেনলিস্টনার কমপক্ষে একবার চালানোর গ্যারান্টিযুক্ত? এই ভবিষ্যতের প্রমাণ?
গ্লেন বেচ

4
@ স্টিলর্যাট আমাকে সলিউশনটি ব্যবহার করার বিপক্ষে থাকবেন তা ঠিক। গুগল কখন এটি পরিবর্তন করে তা আপনি জানেন না, বা এটি সমস্ত অ্যান্ড্রয়েড সংস্করণ বা ডিভাইসে সেভাবে কাজ করে।
গ্লেন বেচ

4
@ স্টিলর্যাট আমি সম্মত, তবে ক্রিয়াকলাপের জীবদ্দশায় এটি একবারের বেশি বলা যেতে পারে? আমি কেবল যুক্তি তৈরি করছি যে এটি যদি এই ক্ষেত্রে কাজ করে তবে এটি খুব মার্জিত সমাধান নয়। আমি মনে করি OnGlobalLayoutListener / Treelistener এটি সম্পর্কে আরও সঠিক উপায়।
গ্লেন বেক

4
সম্ভবত map.moveCamera (ক্যামেরাআপডেটফ্যাক্টরি.স্ক্রোলবাই (1, 1)) যুক্ত করা হচ্ছে; উপরের কোডটি কৌতুক করবে?
আমার

4
setOnCameraChangeListenerএখন
অবচয় করা

56

এই উত্তরগুলি ঠিক আছে, তবে আমি আলাদা পদ্ধতির জন্য যাব, একটি সহজ one মানচিত্রটি প্রকাশের পরে যদি পদ্ধতিটি কেবলমাত্র কাজ করে তবে কেবল এটির জন্য অপেক্ষা করুন:

map.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
    @Override
    public void onMapLoaded() {
        map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 30));
    }
});

4
আমি অনেক পরীক্ষার পরে খুঁজে পেয়েছি যে এই উত্তর এবং ড্যানিয়েলের উপরের সংমিশ্রণটি প্রয়োগ করা দরকার needed কখনও কখনও মানচিত্রটি এখনও লোড করা যায়নি, কখনও কখনও লেআউট এখনও সম্পূর্ণ হয়নি। এগুলির দুটি না হওয়া পর্যন্ত আমি ক্যামেরাকে পছন্দসইভাবে সরানোতে পারি নি।
রবপি

4
দস্তাবেজগুলি থেকে এই পদ্ধতির জন্য সতর্কতা: "সংযোগের কারণে মানচিত্রটি কখনই লোড হয় না, বা যদি মানচিত্রটি ধারাবাহিকভাবে পরিবর্তিত হয় এবং ব্যবহারকারী ক্রমাগত মানচিত্রের সাথে কথোপকথনের কারণে লোডিং কখনই সম্পন্ন করে না তবে এই ইভেন্টটি চালিত হবে না ।" (জোর আমার)।
stkent

4
এটি প্রয়োজনের তুলনায় আরও বেশি বিলম্ব করে কারণ এটি সঠিক অবস্থানে যাওয়ার আগে মানচিত্রের টাইলগুলি ভুল অবস্থানে লোড হওয়ার জন্য অপেক্ষা করে।
জন প্যাটারসন

4
বেশিরভাগ সময় 3-10 সেকেন্ডের মধ্যে আগুন লাগাতে লাগে যা অগ্রহণযোগ্য।
নিমা জি

এটি ক্যামেরা সরানোর জায়গা place আমি মানচিত্রের চেয়ে মানচিত্র.নিমেট ক্যামেরার ব্যবহারের পরামর্শ দেব would মমক্যামেরা
ভারত দোদেজা

51

ঠিক আছে আমি এই কাজ করে। এখানে ডকুমেন্টেড হিসাবে যে এপিআই প্রাক-লেআউট ব্যবহার করা যাবে না।

ব্যবহারের সঠিক API হিসাবে বর্ণিত হয়েছে:

দ্রষ্টব্য: মানচিত্রের লেআউটটি চলে যাওয়ার পরে যদি ক্যামেরাটি স্থানান্তর করতে ব্যবহার করা হয় তবে কেবল ক্যামেরাআউপেটেট তৈরি করতে কেবলমাত্র সহজতর পদ্ধতি ল্যাটল্যাংবাউন্ডস (সীমানা, প্যাডিং) ব্যবহার করুন। লেআউট চলাকালীন, এপিআই মানচিত্রের ডিসপ্লে সীমানা গণনা করে যা সঠিকভাবে বাউন্ডিং বক্সটি প্রজেক্ট করার জন্য প্রয়োজন। তুলনায়, আপনি যে কোনও সময় আরও জটিল পদ্ধতিতে ফিরে নতুন ক্যামেরাউডাউন্ডস (সীমানা, প্রস্থ, উচ্চতা, প্যাডিং) ব্যবহার করতে পারবেন, মানচিত্রের লেআউটটি পেরোনোর ​​আগেই, কারণ আপনার পাস হওয়া আর্গুমেন্টগুলি থেকে এপিআই প্রদর্শন সীমা গণনা করে।

সমস্যা সমাধানের জন্য আমি আমার পর্দার আকার গণনা করেছি এবং প্রস্থ এবং উচ্চতা সরবরাহ করেছি

public static CameraUpdate newLatLngBounds(
    LatLngBounds bounds, int width, int height, int padding)

এটি তখন আমাকে বাউন্ডিং বাক্সের প্রাক-বিন্যাস নির্দিষ্ট করার অনুমতি দেয়।


18
তবে কী যদি মানচিত্র পুরো পর্দাটি না নেয়?
theblang

আমার ক্ষেত্রে আমি কার্যকর হওয়ার চেয়ে আরও বড় স্ক্রিন ধরেছিলাম এবং প্যাডিংটি আরও সাবধানতার সাথে গণনা করা দরকার যাতে এটি খুব বেশি বড় ছিল না । অনেক সহজ কারণ।
rfay

4
আপনি কী স্ক্রিনের আকারের উপর ভিত্তি করে এটি গণনা করবেন তা দেখাতে পারেন?
ড্যানিয়েল গোমেজ রিকো

এটি ক্রাশ হয় না তবে ব্যবহারের জন্য প্রস্থ এবং উচ্চতা খাঁটি অনুমানের কাছাকাছি, আঁকার সঠিক ক্ষেত্রটি সত্যই অনির্দেশ্য।
ভিনস

34

সমাধান এর চেয়ে সহজ ...

// Pan to see all markers in view.
try {
    this.gmap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
} catch (IllegalStateException e) {
    // layout not yet initialized
    final View mapView = getFragmentManager()
       .findFragmentById(R.id.map).getView();
    if (mapView.getViewTreeObserver().isAlive()) {
        mapView.getViewTreeObserver().addOnGlobalLayoutListener(
        new OnGlobalLayoutListener() {
            @SuppressWarnings("deprecation")
            @SuppressLint("NewApi")
            // We check which build version we are using.
            @Override
            public void onGlobalLayout() {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                    mapView.getViewTreeObserver()
                        .removeGlobalOnLayoutListener(this);
                } else {
                    mapView.getViewTreeObserver()
                        .removeOnGlobalLayoutListener(this);
                }
                gmap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
            }
        });
    }
}

IllegalStateExceptionপরিবর্তে বিশ্বব্যাপী শ্রোতাদের ধরুন এবং ব্যবহার করুন। অন্যান্য পদ্ধতি ব্যবহার করে বাউন্ড সাইজটি পূর্বনির্ধারিত (প্রাক-বিন্যাস) সেট করার অর্থ আপনাকে পর্দার ডিভাইস নয়, ভিউয়ের আকারটি গুনতে হবে। আপনি যদি আপনার মানচিত্রের সাথে পূর্ণ স্ক্রিনে যান এবং টুকরোগুলি ব্যবহার না করেন তবে এগুলি কেবল মিলবে match


এখনও
অবধি

4
কিভাবে / কখন এটি ব্যর্থ? এটি নিয়ে কখনও সমস্যা হয়নি। প্রথম উত্তরটি কেবল একটি হার্ডকডযুক্ত আকারকে ফ্যালব্যাক হিসাবে দেয়। "এটি" ক্র্যাশ করে "এটি আর ক্রাশ হয় না" তেমন কাজ করে তবে এটি একই জিনিস করছে না।
ড্যানিয়েলে সেগাটো

@ andrea.spot আমি কেন সহজ বলেছি তা মনে নেই। আমার ধারণা, ইতিমধ্যে গৃহীত সমাধানটি সম্পাদিত হয়েছে। বর্তমান গৃহীত সমাধান অনুমান আপনার মানচিত্রে সব স্ক্রিন, যা সবসময় সত্য নয় নিতে। আপনি যদি সে ক্ষেত্রে না পড়ে থাকেন তবে আপনাকে মানচিত্রের আকার জানতে হবে বা আমার পদ্ধতি বা অনুরূপ কিছু ব্যবহার করতে হবে।
ড্যানিয়েলে সেগাটো

জিংং হুয়াংয়ের নীচের উত্তরটিও দেখুন, এটি এতে কিছুটা যুক্ত করে।
ড্যানিয়েলে সেগাটো

15

এটি আমার ফিক্স, কেবল সেই ক্ষেত্রে মানচিত্রটি লোড হওয়া অবধি অপেক্ষা করুন।

final int padding = getResources().getDimensionPixelSize(R.dimen.spacing);    

try {
    mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(pCameraBounds, padding));
} catch (IllegalStateException ise) {

    mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {

        @Override
        public void onMapLoaded() {
            mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(pCameraBounds, padding));
        }
    });
}

সহজ এবং কার্যকরী + 1
Shid

14

চিহ্নিতকারীদের যুক্ত করা এবং অপসারণ প্রাক-বিন্যাস সমাপ্তি সম্পন্ন করা যেতে পারে, তবে ক্যামেরাটি সরানো যাবে না ( newLatLngBounds(boundary, padding)ওপি-র উত্তরে উল্লিখিত হিসাবে ব্যবহার করা ব্যতীত )।

সম্ভবত সবচেয়ে ভাল জায়গা ইনিশিয়াল ক্যামেরা আপডেট সম্পাদন করার জন্য একটা এক-শটের ব্যবহার করছে OnGlobalLayoutListenerযেমন দেখানো Google এর নমুনা কোড , যেমন থেকে নিম্নোক্ত উদ্ধৃতাংশ দেখতে setUpMap()মধ্যে MarkerDemoActivity.java :

// Pan to see all markers in view.
// Cannot zoom to bounds until the map has a size.
final View mapView = getSupportFragmentManager()
    .findFragmentById(R.id.map).getView();
if (mapView.getViewTreeObserver().isAlive()) {
    mapView.getViewTreeObserver().addOnGlobalLayoutListener(
    new OnGlobalLayoutListener() {
        @SuppressLint("NewApi") // We check which build version we are using.
        @Override
        public void onGlobalLayout() {
            LatLngBounds bounds = new LatLngBounds.Builder()
                    .include(PERTH)
                    .include(SYDNEY)
                    .include(ADELAIDE)
                    .include(BRISBANE)
                    .include(MELBOURNE)
                    .build();
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
              mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            } else {
              mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
            mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
        }
    });
}


ওরিয়েন্টেশন পরিবর্তনে আমি এই ত্রুটিটি পেয়েছি। আমি এটি নমুনা কোড থেকেও পেয়েছি তবে এটি আমার পক্ষে কার্যকর হয়নি। আমি এখনও একই ত্রুটি পেয়েছি।
osrl

14

গৃহীত উত্তরটি আমার পক্ষে কার্যকর হবে না কারণ আমার অ্যাপ্লিকেশনের বিভিন্ন জায়গায় আমাকে একই কোড ব্যবহার করতে হয়েছিল।

ক্যামেরা পরিবর্তিত হওয়ার অপেক্ষার পরিবর্তে, আমি মানচিত্রের আকার নির্দিষ্ট করার পরামর্শ দেওয়ার ভিত্তিতে একটি সহজ সমাধান তৈরি করেছি। আপনার মানচিত্রটি স্ক্রিনের আকারের ক্ষেত্রে এটিই।

// Gets screen size
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
// Calls moveCamera passing screen size as parameters
map.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), width, height, 10));

আশা করি এটি অন্য কাউকে সাহায্য করবে!


8

গৃহীত উত্তরটি হ'ল মন্তব্যগুলিতে উল্লেখ করা হয়েছে, কিছুটা হ্যাকি। এটি প্রয়োগের পরে আমি IllegalStateExceptionবিশ্লেষণে লগগুলির উপরের-গ্রহণযোগ্য পরিমাণ লক্ষ্য করেছি । আমি যে সমাধানটি ব্যবহার করেছি তা হ'ল এটি সম্পাদন করা OnMapLoadedCallbackযা এতে CameraUpdateসম্পাদিত হয়। কলব্যাকটি যুক্ত করা হয়েছেGoogleMap । আপনার মানচিত্র পুরোপুরি লোড হওয়ার পরে ক্যামেরা আপডেট সম্পাদিত হবে।

এর ফলে মানচিত্রটি ক্যামেরা আপডেট সম্পাদনের আগে জুম আউট (0,0) ভিউটি সংক্ষেপে দেখাবে। আমি অনুভব করি যে এটি ক্র্যাশ ঘটানো বা অননুমোদিত আচরণের উপর নির্ভর করার চেয়ে আরও গ্রহণযোগ্য।


5
 map.moveCamera(CameraUpdateFactory.newLatLngZoom(bounds.getCenter(),10));

এটি আমার জন্য কাজ এটি ব্যবহার করুন


এটি কেবল মানচিত্রকে কেন্দ্র করে তবে গতিশীলভাবে সীমানায় জুমকে সামঞ্জস্য করে না।
শাইতানা

আমরা "লাটলংবাউন্ডস.বিল্ডার" ব্যবহার করে আরও ম্যাটারগুলির জন্য সীমানা গণনা করতে পারি।
রমেশ ভূপতি

@ রামেশভূপাতি তবে এটি এখনও কেন্দ্র এবং একটি জুম সহ মানচিত্রের দৃশ্যে থাকবে।
টিমা

4

খুব বিরল ক্ষেত্রে ম্যাপভিউ বিন্যাস সমাপ্ত, তবে গুগলম্যাপ বিন্যাস সমাপ্ত হয়নি, ViewTreeObserver.OnGlobalLayoutListener নিজে ক্র্যাশ থামাতে পারে না। আমি গুগল প্লে পরিষেবা প্যাকেজ সংস্করণ 5084032 এর সাথে ক্র্যাশ দেখেছি my

এই সমস্যার সমাধান করার জন্য, আমি এমবেডেড GoogleMap.OnMapLoadedCallbackমধ্যে onGlobalLayout(),

if (mapView.getViewTreeObserver().isAlive()) {
    mapView.getViewTreeObserver().addOnGlobalLayoutListener(
    new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        @SuppressWarnings("deprecation")
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            } else {
                mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
            try {
                map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 5));
            } catch (IllegalStateException e) {
                map.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
                    @Override
                    public void onMapLoaded() {
                        Log.d(LOG_TAG, "move map camera OnMapLoadedCallback");
                        map.moveCamera(CameraUpdateFactory
                            .newLatLngBounds(bounds, 5));
                    }
                });
            }
        }
    });
}

জবর: আমি refactor যদি mapView.getViewTreeObserver()একটি মধ্যে স্থানীয় পরিবর্তনশীল নিম্নলিখিত ত্রুটি দেখা দেয়: "IllegalStateException এই ViewTreeObserver জীবিত নয়, কল getViewTreeObserver () আবার" । আপনি কি এই চেষ্টা করেছেন?
জেজেডি

। যদি mapView.getViewTreeObserver () isAlive () মিথ্যা হতে ঘটতে আমি map.setOnMapLoadedCallback () জন্য আরো ফলব্যাক এক করা চাই
southerton

4

আমি গুগল ম্যাপস এসডিকে (9.6+) এর সাম্প্রতিক সংস্করণগুলির জন্য এবং অন ক্যামেরাআইডললাইস্টারের উপর ভিত্তি করে বিভিন্ন পদ্ধতির ব্যবহার করেছি । আমি এখন পর্যন্ত দেখতে পাই এটির কলব্যাক পদ্ধতিটি onCameraIdleসর্বদা পরে ডাকা হয় onMapReady। সুতরাং আমার দৃষ্টিভঙ্গিটি কোডের এই অংশের মতো দেখাচ্ছে (এটি বিবেচনা করে দেওয়া হয়েছে Activity):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // set content view and call getMapAsync() on MapFragment
}

@Override
public void onMapReady(GoogleMap googleMap) {
    map = googleMap;
    map.setOnCameraIdleListener(this);
    // other initialization stuff
}

@Override
public void onCameraIdle() {
    /* 
       Here camera is ready and you can operate with it. 
       you can use 2 approaches here:

      1. Update the map with data you need to display and then set
         map.setOnCameraIdleListener(null) to ensure that further events
         will not call unnecessary callback again.

      2. Use local boolean variable which indicates that content on map
         should be updated
    */
}

4

আমি দুটি কলব্যাকগুলি একত্রিত করার একটি উপায় তৈরি করেছি: onMapReady এবং onGlobalLayout কে একটি একক পর্যবেক্ষণযোগ্যতে রূপান্তর করা হবে যা কেবল তখনই প্রকাশিত হবে যখন উভয় ইভেন্টটি ট্রিগার করা হয়েছিল।

https://gist.github.com/abhaysood/e275b3d0937f297980d14b439a8e0d4a


4
এটি প্রকৃতপক্ষে এটি সমাধানের সবচেয়ে সহজ উপায়। আমি এখন দীর্ঘকাল ধরে এটি করছি এবং প্রতিদিন অ্যাপ্লিকেশন 1k ব্যবহারকারী এমনকি বিশ্লেষণে কোনও ত্রুটি ফিরে আসে না। +1
স্কাইল

2

ঠিক আছে আমি একই সমস্যার মুখোমুখি। আমার সাপোর্টম্যাপফ্র্যাগমেন্ট, এবিএস এবং নেভিগেশন ড্রয়ারের সাথে আমার খণ্ড রয়েছে। আমি যা করেছি তা হ'ল:

public void resetCamera() {

    LatLngBounds.Builder builderOfBounds = new LatLngBounds.Builder();
    // Set boundaries ...
    LatLngBounds bounds = builderOfBounds.build();
    CameraUpdate cu;
    try{
        cu = CameraUpdateFactory.newLatLngBounds(bounds,10);
        // This line will cause the exception first times 
        // when map is still not "inflated"
        map.animateCamera(cu); 
        System.out.println("Set with padding");
    } catch(IllegalStateException e) {
        e.printStackTrace();
        cu = CameraUpdateFactory.newLatLngBounds(bounds,400,400,0);
        map.animateCamera(cu);
        System.out.println("Set with wh");
    }

    //do the rest...
}

ও, ভাল কথা, আমি আহ্বান করছি resetCamera()থেকে onCreateViewবৃদ্ধি পরে এবং ফেরার আগে।
এটি যা করে তা প্রথমবার ব্যতিক্রমটি ধরা হয় (যখন মানচিত্রটি বলার উপায় হিসাবে "একটি আকার পায়") এবং তারপরে, অন্য সময় আমাকে ক্যামেরাটি পুনরায় সেট করতে হবে, মানচিত্রে ইতিমধ্যে আকার রয়েছে এবং এটি প্যাডিংয়ের মাধ্যমে করে।

ইস্যুটি ডকুমেন্টেশনে ব্যাখ্যা করা হয়েছে , এতে বলা হয়েছে:

মানচিত্রের লেআউটটি না আসা পর্যন্ত এই ক্যামেরা আপডেটের সাথে ক্যামেরাটি পরিবর্তন করবেন না (যথাযথ সীমানা বাক্স এবং জুম স্তরটি সঠিকভাবে নির্ধারণ করার জন্য, এই মানচিত্রটির অবশ্যই একটি আকার থাকতে হবে)। অন্যথায় একটি IllegalStateExceptionনিক্ষেপ করা হবে। মানচিত্রটি উপলভ্য হওয়ার পক্ষে এটি পর্যাপ্ত নয় (যেমন getMap()একটি নাল অবজেক্ট প্রদান করে); মানচিত্রযুক্ত ভিউটিতে অবশ্যই এর বিন্যাসটি নির্ধারণ করা হয়েছে এমন লেআউটটি অবশ্যই কাটাতে হবে। যদি আপনি নিশ্চিত হতে না পারেন যে এটি ঘটেছে তবে newLatLngBounds(LatLngBounds, int, int, int)পরিবর্তে ব্যবহার করুন এবং মানচিত্রটির মাত্রা ম্যানুয়ালি সরবরাহ করুন।

আমি মনে করি এটি একটি সুন্দর শালীন সমাধান। আশা করি এটি কাউকে সাহায্য করবে।


4
লেআউটটি পুরোপুরি লোড হওয়ার পরে শুনতে কি কোনও শ্রোতা আছে? ?
সাগর নায়ক

ব্যতিক্রম বা উভয় newLatLngBounds()মধ্যে উত্থাপিত হয় animateCamera()? ক্যাচ-ব্রাঞ্চ কী নতুন ব্যতিক্রম ঘটায়?
কুলমাইন্ড

1

আপনার যদি সম্ভাব্য ব্যবহারকারীর ইন্টারঅ্যাকশন শুরু হওয়ার অপেক্ষা করতে OnMapLoadedCallbackহয় তবে পূর্ববর্তী উত্তরে বর্ণিত হিসাবে ব্যবহার করুন । তবে, আপনার যদি প্রয়োজন সমস্ত মানচিত্রের জন্য একটি ডিফল্ট অবস্থান সরবরাহ করা হয় তবে সেই উত্তরগুলিতে বর্ণিত সমাধানগুলির কোনও দরকার নেই। উভয় MapFragmentএবং MapViewগ্রহণ করতে পারেনGoogleMapOptions সূচনা করতে পারে যা ডিফল্ট অবস্থানটি পুরোপুরি সরবরাহ করতে পারে। কেবল কৌশলটি তাদের সরাসরি আপনার বিন্যাসে অন্তর্ভুক্ত করা নয় কারণ সিস্টেমটি তখন বিকল্পগুলি ছাড়া তাদের কল করবে তবে তাদের গতিশীলভাবে আরম্ভ করবে।

আপনার লেআউটে এটি ব্যবহার করুন:

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

এবং খণ্ডটি প্রতিস্থাপন করুন আপনার onCreateView():

GoogleMapOptions options = new GoogleMapOptions();
options.camera(new CameraPosition.Builder().target(location).zoom(15).build());
// other options calls if required

SupportMapFragment fragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
if (fragment == null) {
  FragmentTransaction transaction = getFragmentManager().beginTransaction();
  fragment = SupportMapFragment.newInstance(options);
  transaction.replace(R.id.map, fragment).commit();
  getFragmentManager().executePendingTransactions();
}
if (fragment != null)
  GoogleMap map = fragment.getMap();

শুরুতে দ্রুত হওয়ার পাশাপাশি, প্রথম দেখানো বিশ্ব মানচিত্র এবং দ্বিতীয়বার একটি ক্যামেরা স্থানান্তরিত হবে না। মানচিত্রটি নির্দিষ্ট স্থানে সরাসরি শুরু হবে।


0

আরেকটি পদ্ধতির মতো কিছু হবে (আপনার শীর্ষস্থানীয় দৃষ্টিকে ধরে নেওয়া একটি ফ্রেমলআউট নামক এটি rootContainer, যদিও এটি যতক্ষণ আপনি সর্বদা আপনার শীর্ষস্থানীয় পাত্রে পছন্দ করেন না কেন এটি কোন ধরণের বা নামই থাকুক না কেন):

((FrameLayout)findViewById(R.id.rootContainer)).getViewTreeObserver()
    .addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        public void onGlobalLayout() {
            layoutDone = true;
        }
    });

শুধুমাত্র কাজ আপনার ক্যামেরা ফাংশন পরিবর্তন যদি layoutDoneহয় trueঅতিরিক্ত ফাংশন যোগ করতে অথবা করার যুক্তিবিজ্ঞান আপ টেলিগ্রাম করেও আপনার সব সমস্যার সমাধান হবে layoutListenerহ্যান্ডলার।


0

আমি এটি কাজ করতে পেয়েছি এবং অন্যান্য সমাধানগুলির চেয়ে আরও সাধারণ হতে পেরেছি:

private void moveMapToBounds(final CameraUpdate update) {
    try {
        if (movedMap) {
            // Move map smoothly from the current position.
            map.animateCamera(update);
        } else {
            // Move the map immediately to the starting position.
            map.moveCamera(update);
            movedMap = true;
        }
    } catch (IllegalStateException e) {
        // Map may not be laid out yet.
        getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                moveMapToBounds(update);
            }
        });
    }
}

লেআউট চলার পরে এটি আবার কল চেষ্টা করে। অসীম লুপ এড়াতে সম্ভবত কোনও সুরক্ষা অন্তর্ভুক্ত করা যেতে পারে।


0

কেন এই জাতীয় কিছু ব্যবহার করবেন না:

CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(builder.build(), padding);
try {
    map.moveCamera(cameraUpdate);
} catch (Exception e) {
    int width = getResources().getDisplayMetrics().widthPixels;
    int height = getResources().getDisplayMetrics().heightPixels;
    cameraUpdate = CameraUpdateFactory.newLatLngBounds(builder.build(), width, height, padding);
    map.moveCamera(cameraUpdate);
}

newLatLngBounds(builder.build(), padding)ভিতরে কেন চেষ্টা-ধরা হয় না? এই ব্যতিক্রম কি ঘটবে moveCamera()?
কুলমাইন্ড

0

গুগল ম্যাপস রেপোতে একটি সহায়ক শ্রেণি রয়েছে যা আপনি উত্সাহ অর্জন করতে পারেন - এটি Google মানচিত্রের সাথে একটি কলব্যাক জানানোর আগে লেআউট এবং মানচিত্র উভয় প্রস্তুত হওয়ার জন্য অপেক্ষা করে:

আসল উত্স এখানে:

https://github.com/googlemaps/android-sams/blob/7ee737b8fd6d39c77f8b3716ba948e1ce3730e61/ApiDemos/java/app/src/main/java/com/example/mapdemo/OnMapAndView.eadyListener

একটি কোটলিন বাস্তবায়নও রয়েছে:

https://github.com/googlemaps/android-sample/blob/master/ApiDemos/kotlin/app/src/main/java/com/example/kotlindemos/OnMapAndViewReadyListener.kt

public class OnMapAndViewReadyListener implements OnGlobalLayoutListener, OnMapReadyCallback {

/** A listener that needs to wait for both the GoogleMap and the View to be initialized. */
public interface OnGlobalLayoutAndMapReadyListener {
    void onMapReady(GoogleMap googleMap);
}

private final SupportMapFragment mapFragment;
private final View mapView;
private final OnGlobalLayoutAndMapReadyListener devCallback;

private boolean isViewReady;
private boolean isMapReady;
private GoogleMap googleMap;

public OnMapAndViewReadyListener(
        SupportMapFragment mapFragment, OnGlobalLayoutAndMapReadyListener devCallback) {
    this.mapFragment = mapFragment;
    mapView = mapFragment.getView();
    this.devCallback = devCallback;
    isViewReady = false;
    isMapReady = false;
    googleMap = null;

    registerListeners();
}

private void registerListeners() {
    // View layout.
    if ((mapView.getWidth() != 0) && (mapView.getHeight() != 0)) {
        // View has already completed layout.
        isViewReady = true;
    } else {
        // Map has not undergone layout, register a View observer.
        mapView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    // GoogleMap. Note if the GoogleMap is already ready it will still fire the callback later.
    mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    // NOTE: The GoogleMap API specifies the listener is removed just prior to invocation.
    this.googleMap = googleMap;
    isMapReady = true;
    fireCallbackIfReady();
}

@SuppressWarnings("deprecation")  // We use the new method when supported
@SuppressLint("NewApi")  // We check which build version we are using.
@Override
public void onGlobalLayout() {
    // Remove our listener.
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
    } else {
        mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }
    isViewReady = true;
    fireCallbackIfReady();
}

private void fireCallbackIfReady() {
    if (isViewReady && isMapReady) {
        devCallback.onMapReady(googleMap);
    }
}
}

0

হিসাবে বিবৃত () অসমর্থিত হয়েছে OnCameraChangeListener , setOnCameraChangeListenerবর্তমানে অবচিত হয়েছে। সুতরাং আপনার এটি তিনটি মেটহডের সাথে প্রতিস্থাপন করা উচিত:

  • GoogleMap.OnCameraMoveStartedListener
  • GoogleMap.OnCameraMoveListener
  • GoogleMap.OnCameraIdleListener

আমার ক্ষেত্রে, আমি ব্যবহার করেছি OnCameraIdleListenerএবং অভ্যন্তরে আমি এটিকে সরিয়ে দিয়েছি কারণ এটি যে কোনও আন্দোলনে বারবার অনুরোধ করা হয়েছিল।

googleMap.setOnCameraIdleListener {
    googleMap.setOnCameraIdleListener(null) // It removes the listener.
    googleMap.moveCamera(track)
    googleMap.cameraPosition
    clusterManager!!.cluster()
    // Add another listener to make ClusterManager correctly zoom clusters and markers.
    googleMap.setOnCameraIdleListener(clusterManager)
}

হালনাগাদ

আমি googleMap.setOnCameraIdleListenerআমার প্রকল্পে সরিয়েছি , কারণ যখন কখনও কখনও কোনও মানচিত্র দেখানো হত, তবে এটি ধরে রাখা হত না googleMap.setOnCameraIdleListener(clusterManager)


আপনার জবাবের জন্য ধন্যবাদ। আমি ইতিমধ্যে প্রায় এর মতো সমাধান বের করেছি।
আর্সলান মকবুল

@ আরস্লানমাকবুল, ধন্যবাদ! আমি এখন প্রক্রিয়াধীন এবং আপনি যদি আপনার রূপটি ভাগ করে নেন তবে আপনাকে ধন্যবাদ জানাব।
কুলমাইন্ড

আমার আনন্দ @ কুলমাইন্ড
আর্সলান মকবুল

0

এমএম্যাপ.অ্যানিম্যাট ক্যামেরা কল করতে গিয়ে আমার একই ত্রুটি হয়েছিল। আমি নীচে দেখানো হিসাবে আমার onMapReady ফাংশনে সেটঅনম্যাপলয়েডক্যালব্যাক কলব্যাক কল করে এটি সমাধান করেছি

public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

   // other codes go there

    mMap.setOnMapLoadedCallback(() -> {
            //Your code where exception occurs goes here...
            
        });
}

এটি ভাল কাজ করা উচিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.