কোনও ক্রিয়াকলাপের দৃশ্য অ্যানিমেশন স্থানান্তরের সময় আমি কীভাবে স্থিতি বার এবং নেভিগেশন বারটিকে অ্যানিমেট করা থেকে আটকাতে পারি?


127

প্রথমত, আমার স্ট্যাটাস বারের পটভূমি গা dark় বাদামীতে সেট করা আছে, এবং আমার নেভিগেশন বারের পটভূমি ডিফল্ট কালো। আমি ম্যাটারিয়াল লাইট থিম ব্যবহার করছি।

আমি ActivityOptions.makeSceneTransitionAnimationডিফল্ট রূপান্তরগুলি ব্যবহার করে একটি নতুন ক্রিয়াকলাপ শুরু করছি এবং আমি লক্ষ্য করেছি যে স্থিতি এবং নেভিগেশন বারগুলি উভয়ই সংক্ষিপ্তভাবে সাদা হয়ে যায় এবং তারপরে সঠিক রঙে ফিরে আসে।

ডকুমেন্টেশন অনুযায়ী :

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

আমি getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);উভয় কলিং এবং কল করা ক্রিয়াকলাপগুলিতে ব্যবহার করছি ।

একইভাবে, যদি আমি স্লাইডে প্রবেশের পরিবর্তনটি পরিবর্তন করি তবে স্থিতি এবং নেভিগেশন বার উভয়েরই একটি সাদা পটভূমির সাথে সংক্ষেপে একটি স্লাইড স্থানান্তর রয়েছে।

কোনও ক্রিয়াকলাপের দৃশ্য অ্যানিমেশন স্থানান্তরের সময় আমি কীভাবে স্থিতি বার এবং নেভিগেশন বারটিকে অ্যানিমেট করা থেকে আটকাতে পারি?

উত্তর:


217

স্থানান্তরের সময় নেভিগেশন / স্ট্যাটাস বারটি অ্যানিমেট করা থেকে রোধ করতে আপনি যে দুটি পদ্ধতি ব্যবহার করতে পারেন তা আমি জানি:

পদ্ধতির # 1: উইন্ডোর ডিফল্ট প্রস্থান থেকে স্থিতি দণ্ড এবং নেভিগেশন বারকে বাদ দিন / বিবর্ণ স্থানান্তর প্রবেশ করুন

স্থানান্তরের সময় নেভিগেশন / স্ট্যাটাস বারটি কেন ফিকে হয়ে যায় এবং যে কারণ হ'ল ডিফল্টরূপে সমস্ত অ-ভাগ করা দর্শন (নেভিগেশন / স্ট্যাটাস বারের ব্যাকগ্রাউন্ড সহ) আপনার কলিং / কলকৃত ক্রিয়াকলাপগুলিতে যথাক্রমে সংক্রমণের শুরু হওয়ার পরে / বিবর্ণ হয়ে যায় because । উইন্ডোটির ডিফল্ট প্রস্থান / প্রবেশের Fadeস্থানান্তর থেকে নেভিগেশন / স্ট্যাটাস বারের পটভূমিগুলি বাদ দিয়ে আপনি সহজেই এটি পেতে পারেন । আপনার ক্রিয়াকলাপের onCreate()পদ্ধতিগুলিতে কেবল নিম্নলিখিত কোডটি যুক্ত করুন :

Transition fade = new Fade();
fade.excludeTarget(android.R.id.statusBarBackground, true);
fade.excludeTarget(android.R.id.navigationBarBackground, true);
getWindow().setExitTransition(fade);
getWindow().setEnterTransition(fade);

এই রূপান্তরটি এক্সএমএল (যেমন আপনার নিজের res/transition/window_fade.xmlফাইলে) ব্যবহার করে ক্রিয়াকলাপের থিমেও ঘোষণা করা যেতে পারে :

<?xml version="1.0" encoding="utf-8"?>
<fade xmlns:android="http://schemas.android.com/apk/res/android">
    <targets>
        <target android:excludeId="@android:id/statusBarBackground"/>
        <target android:excludeId="@android:id/navigationBarBackground"/>
    </targets>
</fade>

পদ্ধতির # 2: ভাগ করা উপাদান হিসাবে স্থিতি দণ্ড এবং নেভিগেশন বার যুক্ত করুন

এই পদ্ধতির Klmprt এর উত্তর বন্ধ করে দেয়, যা প্রায় আমার জন্য কাজ করেছিল ... যদিও আমাকে এখনও বেশ কয়েকটি পরিবর্তন করার প্রয়োজন ছিল।

আমার কলিং ক্রিয়াকলাপে, ক্রিয়াকলাপ শুরু করতে আমি নিম্নলিখিত কোডটি ব্যবহার করেছি:

View statusBar = findViewById(android.R.id.statusBarBackground);
View navigationBar = findViewById(android.R.id.navigationBarBackground);

List<Pair<View, String>> pairs = new ArrayList<>();
if (statusBar != null) {
  pairs.add(Pair.create(statusBar, Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME));
}
if (navigationBar != null) {
  pairs.add(Pair.create(navigationBar, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
}
pairs.add(Pair.create(mSharedElement, mSharedElement.getTransitionName()));

Bundle options = ActivityOptions.makeSceneTransitionAnimation(activity, 
        pairs.toArray(new Pair[pairs.size()])).toBundle();
startActivity(new Intent(context, NextActivity.class), options);

এখনও অবধি এটি মূলত একই জিনিস যা তার উত্তরে klmprt পরামর্শ দিয়েছে। তবে, onCreate()স্থিতি দণ্ড এবং নেভিগেশন বারটিকে "জ্বলজ্বল" থেকে সংক্রমণ চলাকালীন আটকাতে আমার নামক ক্রিয়াকলাপের পদ্ধতিতে নিম্নলিখিত কোডটি যুক্ত করা দরকার :

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

    // Postpone the transition until the window's decor view has
    // finished its layout.
    postponeEnterTransition();

    final View decor = getWindow().getDecorView();
    decor.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            decor.getViewTreeObserver().removeOnPreDrawListener(this);
            startPostponedEnterTransition();
            return true;
        }
    });
}

অংশীদারি উপাদান হিসাবে স্ট্যাটাস বার এবং নেভিগেশন বারের পটভূমি যুক্ত করা উইন্ডোটির ডিফল্ট প্রস্থানের উপরের দিকে আঁকতে বাধ্য করবে / বিবর্ণ ট্রানজিশন প্রবেশ করবে, যার অর্থ তারা উত্তরণের সময় বিবর্ণ হবে না। এই পদ্ধতির সম্পর্কে আরও আলোচনা এই Google+ পোস্টে পাওয়া যাবে ।


14
কোনও ধারণা কেন FindViewById (android.R.id.navicationBarBackground) ললিপপের পিছনে ফিরে যাচ্ছে? আমি অ্যাপকম্প্যাট-
ভি

3
পদ্ধতির # 2 কাজ করে, তবে রূপান্তর ঘটে গেলে এখনও একটি ফ্লিকার (ক্রিয়াকলাপে) থাকে। স্ট্যাটাস বার এবং নেভিগেশন বারটি আর ফ্লিকার করে না।
অক্ষত

16
@ অ্যালেক্স আমাদের জন্য প্রায় নিখুঁতভাবে কাজ করেছে যতক্ষণ না আমরা অ্যান্ড্রয়েড.সুপুরপোর্ট.ডিজাইন.উইডজেট.ড্যাবলয়আউট এবং android.support.design.widget.appBarLayout- এর সাহায্যে নতুন সমর্থন লাইব্রেরিতে স্যুইচ করি না - এখন ঝলকানি ফিরে এসেছে
নোয়া ড্রচ

6
অ্যান্ড্রয়েড.আর.আইড.নভিগেশনবারব্যাকগ্রাউন্ড আপনাকে স্যামসুং বা এইচটিসি ডিভাইসগুলিতে একটি এনপিই দিতে পারে কারণ তাদের স্ক্রিন নেভিগেশন বার নেই। তাদের ভাগ করা উপাদান হিসাবে যুক্ত করার আগে নাল চেক করুন
বয়

8
আমি অ্যান্ড্রয়েড নুগ্যাট সহ নেক্সাস 6 এ এই সমাধানটি চেষ্টা করছি। তবে উভয় পদ্ধতিরই আমার পক্ষে কাজ করছে না।
পারদীপ কেআর

4

ক্রিয়াকলাপ স্থানান্তরগুলি ভাগ করে নেওয়া উপাদানগুলির স্থানান্তরের সাথে হস্তক্ষেপ থেকে সম্পূর্ণরূপে প্রতিরোধ করে:

উপস্থিত থাকা ক্রিয়াকলাপে getWindow ()। SetExitTransition (নাল) কল করুন;

প্রবেশের ক্রিয়াকলাপে getWindow ()। SetEnterTransition (নাল) কল করুন;

Https://stackoverflow.com/a/34907685/967131 থেকে

আমার সন্দেহ হয় এর পার্শ্ব প্রতিক্রিয়া থাকতে পারে, তবে নিশ্চিত করে জানিনা। এটি মৃত সহজ এবং যদিও কাজ করে।

নির্দিষ্ট উপাদানগুলিকে ঝলকানো থেকে বিরত রাখুন:

আমি অ্যালেক্স লকউডের উত্তর দিয়ে শুরু করেছিলাম এবং এটি কার্যকর করার চেষ্টা করার জন্য আমি মোটামুটি পরীক্ষা-নিরীক্ষা করেছি। এর মূলটি সঠিক, যদিও আমার ক্রিয়াকলাপ গ্রহণের জন্য প্রস্তাবিত কোডটির প্রয়োজন ছিল না, তবে আমি এটিকে কোনও ক্রিয়াকলাপের পরিবর্তে (ক্রিয়াকলাপের পরিবর্তে) কল করে এবং অ্যাকশন বার হিসাবে একটি সরঞ্জামদণ্ড সেট করে কিছু সমস্যার মধ্যে পড়েছিলাম।

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

শেষ পর্যন্ত, আমি এই ইউটিলিটি পদ্ধতিটি বিকাশ করেছি:

public static Bundle transitionOptions(Activity activity, int transitionViewResId, int transitionNameResId) {
   if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
       return null;
   }

   View decorView = activity.getWindow().getDecorView();
   View statusBar = decorView.findViewById(android.R.id.statusBarBackground);
   View navigationBar = decorView.findViewById(android.R.id.navigationBarBackground);
   View appBarLayout = decorView.findViewById(**R.id.appbarlayout**);
   View transitionView = decorView.findViewById(transitionViewResId);
   String transitionName = activity.getString(transitionNameResId);

   List<Pair<View, String>> pairs = new ArrayList<>();
   pairs.add(Pair.create(statusBar, Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME));
   pairs.add(Pair.create(navigationBar, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
   if (appBarLayout != null) {
       pairs.add(Pair.create(appBarLayout, activity.getString(**R.string.transition_appbarlayout**)));
   }
   pairs.add(Pair.create(transitionView, transitionName));
   //noinspection unchecked - we're not worried about the "unchecked" conversion of List<Pair> to Pair[] here
   return ActivityOptionsCompat.makeSceneTransitionAnimation(activity, pairs.toArray(new Pair[pairs.size()]))
           .toBundle();
}

R.string.transition_appbarlayout এবং R.id.appbarlayout নোট করুন । এই আইডিগুলি যতক্ষণ না আপনার কোড ব্যবহার করে সেগুলির সাথে মেলে ততক্ষণ তা নির্বিচারে। আমার এক্সএমএলে, আমি কাস্টম অ্যাকশন বারটির মতো লেআউট করি (প্রয়োজনীয়গুলি সম্পাদনা করে):

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
    android:id="**@+id/appbarlayout**"
    android:transitionName="**@string/transition_appbarlayout**">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"/>
</android.support.design.widget.AppBarLayout>

আপনি যদি এর মতো কোনও সরঞ্জামদণ্ড ব্যবহার না করেন তবে সেই অংশটি ইউটিলিটি পদ্ধতি থেকে সরানো যেতে পারে।

তারপরে আপনি এটিকে আপনার খণ্ডগুলিতে এভাবে ডাকবেন:

startActivity(intent, UIUtils.transitionOptions(getActivity(),
                        R.id.**my_view**,
                        R.string.**transition_my_view**));

যতক্ষণ না এটি আপনার এক্সএমএলের সাথে মেলে ততক্ষণ মানগুলি ব্যবহার করুন।

এটি স্থিতি দণ্ড, সরঞ্জাম দণ্ড এবং নেভিগেশন বার (পিছনে / হোম / সাম্প্রতিক অ্যাপ্লিকেশন বোতাম) স্থানান্তরকালে ফ্ল্যাশিং থেকে বাধা দেয়। ক্রিয়াকলাপের বাকী অংশটি স্বাভাবিক।

আমার ক্ষেত্রে, আমাদের অ্যাপ্লিকেশন থিমের android:windowBackgroundনীল রঙ রয়েছে। এটি রূপান্তরটিতে একটি নীল ফ্ল্যাশ সৃষ্টি করে, যা বেশ হতাশাব্যঞ্জক। পরিবর্তে এর পরিবর্তে পুরো অ্যাপ্লিকেশনটিকে প্রভাবিত করে, আপাতত আমি প্রথম, দ্রুত এবং নোংরা বিকল্পটি নিয়ে যাচ্ছি।


3

এগুলিতে আপনাকে ভাগ করে নেওয়া দরকার ActivityOptions.makeSceneTransitionAnimation.

উদাহরণ:

ActivityOptions.makeSceneTransitionAnimation(... Pair.create(activity.findViewById(android.R.id.window_status_bar), Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME) 

(স্যুইচিডোকে ক্ষমা করুন; আমার হাতে অ্যান্ড্রয়েড.আর.আইডি মান নেই)

মতামত ভাগ করে নেওয়ার পরে আপনি একটি উপযুক্ত ট্রানজিশন চালাতে পারেন।


এই কাজ কি তোমার জন্য ছিল? আমি এটি চেষ্টা করেছি এবং স্থিতি দণ্ড এবং নেভিগেশন বারটি রূপান্তরকালে এখনও সাদা ঝলকান।
rlay3

হ্যাঁ, এটি আমার পক্ষে কাজ করেছিল। আপনি কি নিশ্চিত যে এমন কোনও দৃশ্য নেই যা সেগুলি অস্থায়ীভাবে ওভারল্যাপ করে? সমস্যাটি বিচ্ছিন্ন করার জন্য আপনি কি কোনও 'স্যান্ডবক্সযুক্ত' পরিবেশে একটি সহজ ক্রিয়াকলাপটি স্থানান্তরিত করার চেষ্টা করেছেন?
klmprt

@klmprt আমি মনে করি এটির কাজটি চালানোর জন্য আপনার প্রবেশের স্থিতি স্থগিত করা দরকার ... আমি মতামতগুলি ভাগ করে কেবল স্থিতি / নেভিগেশন বারগুলি অ্যানিমেটেড করা থেকে আটকাতে পারি নি। আমার ধারনা আপনি প্রবেশের ট্রানজিশনটি শুরু করার আগে উইন্ডোটির সজ্জা দর্শনটির লেআউটটি শেষ করার জন্য অপেক্ষা করতে হবে।
অ্যালেক্স লকউড

@klmprt আমার উত্তরটি এখনও কী সমাধান করে না তা হ'ল কীভাবে অ্যাকশন বারের পটভূমির রঙটি সংক্রমণের সময় অ্যানিমেট করা থেকে রোধ করা যায়। যদি ক্রিয়াকলাপের উভয়ই একই অ্যাকশন বারের পটভূমির রঙ ভাগ করে, তবে কলিং ক্রিয়াকলাপের অ্যাকশন বারটি ধীরে ধীরে বিবর্ণ হয়ে যায় এবং কলকৃত ক্রিয়াকলাপের অ্যাকশন বারটি মৃদুভাবে ম্লান হয়ে যায় this আপনার কী ধারণা রয়েছে আপনার কীভাবে এই চারপাশে যাবেন? সমস্যা?
অ্যালেক্স লকউড

@klmprt আসলে, আমি মনে করি এর থেকেও আরও ভাল সমাধান রয়েছে। আপনি কেবল উইন্ডোটির ডিফল্ট প্রস্থানটিতে টার্গেট হিসাবে নেভিগেশন / স্ট্যাটাস বারের পটভূমি বাদ দিতে পারেন / বিবর্ণ রূপান্তর প্রবেশ করুন। বিশদ জন্য আমার আপডেট উত্তর দেখুন।
অ্যালেক্স লকউড

3

যতদূর আমি বুঝতে পারি এটি ক্রিয়াকলাপের স্থানান্তর ওভারল্যাপের কারণে ঘটে। এই সমস্যাটি কাটিয়ে উঠতে আমি onCreate()উভয় ক্রিয়াকলাপের পদ্ধতিতে নিম্নলিখিত মানগুলি ব্যবহার করেছি :

getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setAllowReturnTransitionOverlap(false);

3

আমার সবেমাত্র এই একই সমস্যা ছিল এবং উত্তরগুলি ধাঁধাটির কাছে একটি সমালোচনামূলক অংশ হারিয়েছে বলে মনে হচ্ছে। মনে রাখবেন যে একটি ভাগ করা উপাদান পরিবর্তনের সময়, গন্তব্য ক্রিয়াকলাপে সবকিছু ঘটে ।

ঝলকানি প্রভাবটি সরাতে, ক্রিয়াকলাপটির জন্য কেবল নিম্নলিখিতটি যুক্ত করুন:

Fade fade = new Fade();
fade.excludeTarget(android.R.id.statusBarBackground, true);
fade.excludeTarget(android.R.id.navigationBarBackground, true);

getWindow().setEnterTransition(fade);
getWindow().setExitTransition(fade);

এটা আপনার সমস্যা সমাধান করবে!


ওহে. এটি শীর্ষ উত্তরের অ্যাপ্রোচ # 1 এর মতো নয়?
rlay3

@ rlay3 সম্পূর্ণরূপে নয়। আমি যতদূর বলতে পারি, তিনি কখনই এই সত্যটির উল্লেখ করেননি যে এটি কেবল গন্তব্য ক্রিয়াকলাপে সেট করা উচিত।
লুক ওয়াগনয়ের

আরে @LukeWaggoner তুমি আমাকে সাহায্য করতে পারে এই stackoverflow.com/questions/50189286/...
Blackhawk

আপনাকে অবশ্যই স্ট্যাটাস বার এবং নেভিগেশনবার উভয় ক্রিয়াকলাপ, কলার এবং কল হিসাবে বাদ দিতে হবে।
জিওভান্নি ডি গ্রেগরিও


0

এখানে আমি এটি কীভাবে করেছি। আমি উভয় ভাগ Status Barএবং Navigation BarSharedElementTransitionএকটি সহ ImageView:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  View imageView = view.findViewById(R.id.iv);
  Resources resources = view.getResources();
  imageView.setTransitionName(resources.getString(R.string.transition_image_thumbnail));

  Pair<View, String> p1 = Pair.create(imageView, resources.getString(R.string.transition_image_thumbnail));

  Window window = getActivity().getWindow();

  View navigationBar = getActivity().findViewById(android.R.id.navigationBarBackground);
  View statusBar = getActivity().findViewById(android.R.id.statusBarBackground);

  Pair<View, String> p2 = Pair.create(statusBar, statusBar.getTransitionName());
  Pair<View, String> p3 = Pair.create(navigationBar, navigationBar.getTransitionName());

  ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(),
          p1, p2, p3);

  ActivityCompat.startActivity(getActivity(), intent, options.toBundle());
} else {
  startActivity(intent);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.