স্থানান্তরের অ্যানিমেশনের সময় নেস্টেড টুকরোগুলি অদৃশ্য হয়ে যায়


100

এখানে দৃশ্যধারণ করা হয়েছে: ক্রিয়াকলাপে টুকরো টুকরো রয়েছে Aযা getChildFragmentManager()ফলস্বরূপ টুকরা যোগ করতে A1এবং A2এর onCreateমতো করে ব্যবহার করে :

getChildFragmentManager()
  .beginTransaction()
  .replace(R.id.fragmentOneHolder, new FragmentA1())
  .replace(R.id.fragmentTwoHolder, new FragmentA2())
  .commit()

এতক্ষণ, এত ভাল, সবকিছু প্রত্যাশার মতো চলছে।

তারপরে আমরা ক্রিয়াকলাপে নিম্নলিখিত লেনদেনটি পরিচালনা করি:

getSupportFragmentManager()
  .beginTransaction()
  .setCustomAnimations(anim1, anim2, anim1, anim2)
  .replace(R.id.fragmentHolder, new FragmentB())
  .addToBackStack(null)
  .commit()

সংক্রমণের সময়, enterখণ্ডের জন্য অ্যানিমেশনগুলি Bসঠিকভাবে চলে তবে টুকরো A1 এবং A2 পুরোপুরি অদৃশ্য হয়ে যায় । আমরা যখন পিছনে বোতামটি দিয়ে লেনদেনটি ফিরিয়ে দিই, সেগুলি যথাযথভাবে শুরু হয় এবং popEnterঅ্যানিমেশনের সময় সাধারণত প্রদর্শিত হয় ।

আমার সংক্ষিপ্ত পরীক্ষায় এটি অদ্ভুত হয়ে উঠল - যদি আমি শিশু খণ্ডগুলির জন্য অ্যানিমেশনগুলি সেট করি (নীচে দেখুন), exitঅধ্যায়টি যখন আমরা টুকরো যোগ করি তখন মাঝেমধ্যে চলতে থাকেB

getChildFragmentManager()
  .beginTransaction()
  .setCustomAnimations(enter, exit)
  .replace(R.id.fragmentOneHolder, new FragmentA1())
  .replace(R.id.fragmentTwoHolder, new FragmentA2())
  .commit()

আমি যে প্রভাবটি অর্জন করতে চাই তা সহজ - আমি খুব সহজেই exit(বা এটি হওয়া উচিত popExit?) অ্যানিমেশনটি খণ্ডগুলিতে A(অ্যানিম 2) চালাতে চাই, তার ঘরোয়া বাচ্চাদের সহ পুরো পাত্রে অ্যানিমেট করে।

এটি অর্জন করার কোনও উপায় আছে কি?

সম্পাদনা করুন : দয়া করে এখানে একটি পরীক্ষার কেস সন্ধান করুন

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


R.id.fragmentHolderএ, এ 1, এ 2, ইত্যাদি সম্পর্কে সম্মান কী ?
কমন্সওয়্যার

ফ্র্যাগমেন্টহোল্ডার ক্রিয়াকলাপের লেআউটে একটি আইডি, খণ্ড {এক, দুই} ধারক খণ্ড খ এর লেআউটে থাকে। তিনটিই স্বতন্ত্র। খণ্ড A এ প্রাথমিকভাবে ফ্রেগমেন্টহোল্ডারে যুক্ত করা হয়েছিল (অর্থাত, খণ্ড বি বি খণ্ড A এর স্থলাভুক্ত করছে)।
ডিলিয়ান

আমি এখানে একটি নমুনা প্রকল্প তৈরি করেছি: github.com/BurntBrunch/ নেস্টেড ফ্রেমস অ্যানিমেশন টেস্ট , সংগ্রহস্থলের মধ্যে একটি apk অন্তর্ভুক্ত রয়েছে। এটি একটি সত্যই বিরক্তিকর ত্রুটিযুক্ত এবং আমি এর চারপাশে কাজ করার উপায় খুঁজছি (ধরে নিলাম এটি আমার কোডে নেই)।
ডিলিয়ান

আমি এই সমস্যাটি সম্পর্কে এখন আরও কিছু জানি। খণ্ডগুলি অদৃশ্য হওয়ার কারণ শিশুরা পিতামাতার সামনে জীবনচক্রের ঘটনাগুলি পরিচালনা করে। সংক্ষেপে, A1 এবং A2 এ এর ​​আগে সরিয়ে ফেলা হয় এবং যেহেতু তাদের এনিমেশন সেট নেই, সেগুলি হঠাৎ অদৃশ্য হয়ে যায়। কিছুটা প্রশমিত করার একটি উপায় হ'ল এ-এর পরিবর্তে লেনদেনের স্পষ্টভাবে A1 এবং A2 মুছে ফেলা, এইভাবে, তারা প্রস্থান করার সময় এনিমেট করে, তবে তাদের অ্যানিমেশনের গতি বর্গক্ষেত্র হয়, যেহেতু প্যারেন্ট পাত্রেও অ্যানিমেশন থাকে। একটি সমাধান যা এই শৈল্পিক উত্পাদন করে না প্রশংসা করা হবে।
ডিলিয়ান

প্রশ্নটিতে আপনি যে পরিবর্তন (স্টার্টার টুকরা প্রতিস্থাপন করে) উল্লেখ করেছেন তা হ'ল আপনি যা করতে চান তা আসল নাকি এটি একটি উদাহরণ? আপনি কি একবারে changeFragmentপদ্ধতিটি কল করবেন ?
Luksprog

উত্তর:


36

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

আমি ব্যাকগ্রাউন্ড ইমেজ সেট করার সাথে একটি সামান্য উদাহরণ তৈরি করেছি (প্রাথমিক কিছু)।


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

16
বাহ, এত নোংরা। অ্যান্ড্রয়েড বিকাশকারীদের যে দৈর্ঘ্যগুলি আমাদের কিছুটা চটকাতে হবে
ডিন ওয়াইল্ড

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

ব্যবহারকারী যখন @ হরিশ লিখেছেন তেমন সমস্যা ফিরে আসে
ইওকস

1
ওয়াও সিরিয়াসলি? এর 2018 এবং এটি এখনও একটি জিনিস? :(
আর্চি জি কুইনস

69

সুতরাং এটির জন্য অনেকগুলি আলাদা আলাদা কাজ রয়েছে বলে মনে হয় তবে @ জেডি 16 এর উত্তরের ভিত্তিতে আমি মনে করি যে আমি একটি দুর্দান্ত দৃ catch় ক্যাচ-অল সলিউশন পেয়েছি যা এখনও শিশু খণ্ডগুলিতে কাস্টম ট্রানজিশন অ্যানিমেশনগুলিকে মঞ্জুরি দেয় এবং এর জন্য প্রয়োজন হয় না doing বিন্যাসের একটি বিটম্যাপ ক্যাশে।

একটি BaseFragmentবর্গ বাড়ান যা প্রসারিত হয় Fragmentএবং আপনার সমস্ত টুকরো সেই শ্রেণিটিকে প্রসারিত করুন (কেবলমাত্র শিশু টুকরা নয়)।

এই BaseFragmentশ্রেণিতে, নিম্নলিখিতগুলি যুক্ত করুন:

// Arbitrary value; set it to some reasonable default
private static final int DEFAULT_CHILD_ANIMATION_DURATION = 250;

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    final Fragment parent = getParentFragment();

    // Apply the workaround only if this is a child fragment, and the parent
    // is being removed.
    if (!enter && parent != null && parent.isRemoving()) {
        // This is a workaround for the bug where child fragments disappear when
        // the parent is removed (as all children are first removed from the parent)
        // See https://code.google.com/p/android/issues/detail?id=55228
        Animation doNothingAnim = new AlphaAnimation(1, 1);
        doNothingAnim.setDuration(getNextAnimationDuration(parent, DEFAULT_CHILD_ANIMATION_DURATION));
        return doNothingAnim;
    } else {
        return super.onCreateAnimation(transit, enter, nextAnim);
    }
}

private static long getNextAnimationDuration(Fragment fragment, long defValue) {
    try {
        // Attempt to get the resource ID of the next animation that
        // will be applied to the given fragment.
        Field nextAnimField = Fragment.class.getDeclaredField("mNextAnim");
        nextAnimField.setAccessible(true);
        int nextAnimResource = nextAnimField.getInt(fragment);
        Animation nextAnim = AnimationUtils.loadAnimation(fragment.getActivity(), nextAnimResource);

        // ...and if it can be loaded, return that animation's duration
        return (nextAnim == null) ? defValue : nextAnim.getDuration();
    } catch (NoSuchFieldException|IllegalAccessException|Resources.NotFoundException ex) {
        Log.w(TAG, "Unable to load next animation from parent.", ex);
        return defValue;
    }
}

দুর্ভাগ্যক্রমে এর প্রতিবিম্ব প্রয়োজন; তবে, যেহেতু এই কর্মক্ষেত্রটি সমর্থন লাইব্রেরির জন্য, আপনি যদি আপনার সমর্থন লাইব্রেরি আপডেট না করেন তবে আপনি অন্তর্নিহিত বাস্তবায়নের ঝুঁকিটি চালাবেন না। আপনি যদি উত্স থেকে সহায়তা গ্রন্থাগারটি তৈরি করে থাকেন তবে আপনি পরবর্তী অ্যানিমেশন রিসোর্স আইডির জন্য একটি এক্সেসর যুক্ত করতে Fragment.javaএবং প্রতিবিম্বের প্রয়োজনীয়তা সরিয়ে ফেলতে পারেন।

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


5
এটি থ্রেডে আমার প্রিয় সমাধান। বিটম্যাপের প্রয়োজন হয় না, শিশু খণ্ডে কোনও অতিরিক্ত কোডের প্রয়োজন হয় না, এবং সত্যই পিতামাতার কাছ থেকে শিশু খণ্ডে তথ্য ফাঁস করে না।

1
@ ইউজেনপ্যাচেনেক আপনার পিতা - মাতার টুকরোটি থেকে পরবর্তী পরবর্তী প্রয়োজন - সন্তানের নয় from এই হল ব্যপার.
কেভিন কপক 21

1
দুর্ভাগ্যক্রমে এই পদ্ধতির ফলে শিশুর টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো হয়ে যায় এবং ললিপপের নীচে অ্যান্ড্রয়েড সংস্করণগুলিতে
স্পষ্টতই

8
এই অত্যন্ত কার্যকর সমাধানের জন্য আপনাকে ধন্যবাদ, তবে বর্তমান সমর্থন লাইব্রেরিটির সাথে কাজ করার জন্য এটির জন্য সামান্য আপডেটের প্রয়োজন (27.0.2, কোন সংস্করণটি এই কোডটি ভেঙেছে তা জানেন না)। mNextAnimএখন একটি mAnimationInfoবস্তুর ভিতরে । আপনি এটির মতো এটি অ্যাক্সেস করতে পারেন:Field animInfoField = Fragment.class.getDeclaredField("mAnimationInfo"); animInfoField.setAccessible(true); Object animationInfo = animInfoField.get(fragment); Field nextAnimField = animationInfo.getClass().getDeclaredField("mNextAnim");
ডেভিড লেরিকোলাইস

5
@ ডেভিডলেরিকোলাইস, আপনার পরে আরও একটি লাইন কোড যুক্ত করতে চাই। val nextAnimResource = nextAnimField.getInt(animationInfo);লাইনটি প্রতিস্থাপন করতেint nextAnimResource = nextAnimField.getInt(fragment);
tingyik90

32

আমি একটি সুন্দর পরিষ্কার সমাধান নিয়ে আসতে সক্ষম হয়েছি। আইএমও এটির সর্বনিম্ন হ্যাকি, এবং এটি প্রযুক্তিগতভাবে "বিটম্যাপ আঁকুন" সমাধান হ'ল কমপক্ষে বিভক্ত লিব দ্বারা বিমুক্ত।

নিশ্চিত করুন যে আপনার সন্তানের ফ্রেগগুলি এর সাথে একটি পিতামাতার শ্রেণিকে ওভাররাইড করে:

private static final Animation dummyAnimation = new AlphaAnimation(1,1);
static{
    dummyAnimation.setDuration(500);
}

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
    if(!enter && getParentFragment() != null){
        return dummyAnimation;
    }
    return super.onCreateAnimation(transit, enter, nextAnim);
}

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

আমি কেবলমাত্র ইস্যুটি ভাবতে পারি তা হল সেই সময়কালের ট্র্যাক রাখা। আমি সম্ভবত এটি একটি বৃহত-ইশ সংখ্যায় সেট করতে পারি তবে আমি ভয় করি যে এর অ্যানিমেশনটি অন্য কোথাও আঁকলে পারফরম্যান্সের সমস্যা থাকতে পারে।


ধন্যবাদ, ধন্যবাদ। সময়কাল সময়ের মান মূল্য দেয় না
ইস্পেরিয়ট

এখনও অবধি পরিষ্কার সমাধান
লিরান কোহেন

16

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

getChildFragmentManager().beginTransaction()
        .setCustomAnimations(R.anim.none, R.anim.none, R.anim.none, R.anim.none)
        .add(R.id.container, nestedFragment)
        .commit();

R.anim.none এর জন্য এক্সএমএল (আমার বাবা-মা প্রবেশ / প্রস্থান অ্যানিমেশন সময় 250 মিমি)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="0" android:duration="250" />
</set>

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

এই দুর্দান্ত ছিল। যাইহোক, আমার সন্তানের টুকরাগুলি স্যুইচ করার সময় আমি বিলম্ব পাচ্ছিলাম। এটি এড়াতে, কোনও আনিম ছাড়াই কেবল ২ য় প্যারামিটারটি সেট করুন:fragmentTransaction.setCustomAnimations(R.anim.none, 0, R.anim.none, R.anim.none)
ওনে

7

আমি বুঝতে পেরেছি এটি আপনার সমস্যার সম্পূর্ণ সমাধান করতে সক্ষম নাও হতে পারে তবে এটি অন্য কারওর প্রয়োজন অনুসারে উপযুক্ত হবে, আপনি আপনার বাচ্চাদের জন্য enter/ exitএবং popEnter/ popExitঅ্যানিমেশনগুলি যুক্ত করতে পারেন Fragmentযা প্রকৃতপক্ষে সরানো / প্রাণবন্ত হয় না Fragment। যতক্ষণ অ্যানিমেশনগুলির প্যারেন্ট Fragmentঅ্যানিমেশনগুলির একই সময়কাল / অফসেট থাকে ততক্ষণ তারা পিতামাতার অ্যানিমেশন সহ স্থানান্তর / অ্যানিমেটে উপস্থিত হবে।


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

সম্মত, এটি জলরোধী দ্রবণের চেয়ে কার্যকরী বেশি এবং এটিকে সামান্য ভঙ্গুর হিসাবে বিবেচনা করা যেতে পারে। তবে এটি সহজ ক্ষেত্রে কাজ করবে।
স্টিভেন বাইলে

4

আপনি শিশু খণ্ডে এটি করতে পারেন।

@Override
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
    if (true) {//condition
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(getView(), "alpha", 1, 1);
        objectAnimator.setDuration(333);//time same with parent fragment's animation
        return objectAnimator;
    }
    return super.onCreateAnimator(transit, enter, nextAnim);
}

ধন্যবাদ! সম্ভবত সেরা না হলেও সম্ভবত সবচেয়ে সহজ সমাধান।
বাগ56

2

@@@@@@@@@@@@@@@@@@@@@@@@@@@@

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

http://corner.squareup.com/2014/01/mortar-and-flow.html

@@@@@@@@@@@@@@@@@@@@@@@@@@@@

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

যেহেতু আমি সমস্ত জায়গাতেই শিশু খণ্ডগুলি ব্যবহার করি আমি এই সমাধানটি কার্যকরভাবে নিয়ে এসেছি যা কার্যকর এবং মডুলার (যাতে এটি সহজেই মুছে ফেলা যায়) যদি তারা কখনও এটিকে ঠিক করে দেয় এবং এই নো-অপশন অ্যানিমেশনটির আর প্রয়োজন নেই।

আপনি এটি প্রয়োগ করতে পারেন এমন অনেকগুলি উপায় রয়েছে। আমি একটি সিঙ্গলটন ব্যবহার করা বেছে নিয়েছি এবং আমি এটিকে চাইল্ডফ্রেগমেন্টএনিমেশনম্যানেজার বলি। এটি মূলত তার পিতামাতার উপর ভিত্তি করে আমার জন্য একটি শিশু খণ্ডের উপর নজর রাখবে এবং জিজ্ঞাসা করা হলে বাচ্চাদের জন্য কোনও অপ-অ্যানিমেশন প্রয়োগ করবে।

public class ChildFragmentAnimationManager {

private static ChildFragmentAnimationManager instance = null;

private Map<Fragment, List<Fragment>> fragmentMap;

private ChildFragmentAnimationManager() {
    fragmentMap = new HashMap<Fragment, List<Fragment>>();
}

public static ChildFragmentAnimationManager instance() {
    if (instance == null) {
        instance = new ChildFragmentAnimationManager();
    }
    return instance;
}

public FragmentTransaction animate(FragmentTransaction ft, Fragment parent) {
    List<Fragment> children = getChildren(parent);

    ft.setCustomAnimations(R.anim.no_anim, R.anim.no_anim, R.anim.no_anim, R.anim.no_anim);
    for (Fragment child : children) {
        ft.remove(child);
    }

    return ft;
}

public void putChild(Fragment parent, Fragment child) {
    List<Fragment> children = getChildren(parent);
    children.add(child);
}

public void removeChild(Fragment parent, Fragment child) {
    List<Fragment> children = getChildren(parent);
    children.remove(child);
}

private List<Fragment> getChildren(Fragment parent) {
    List<Fragment> children;

    if ( fragmentMap.containsKey(parent) ) {
        children = fragmentMap.get(parent);
    } else {
        children = new ArrayList<Fragment>(3);
        fragmentMap.put(parent, children);
    }

    return children;
}

}

এরপরে আপনার এমন একটি শ্রেণি থাকতে হবে যা আপনার সমস্ত খণ্ডগুলি প্রসারিত করে (কমপক্ষে আপনার শিশু খণ্ড) Fra আমার এই ক্লাসটি ইতিমধ্যে ছিল এবং আমি এটিকে বেসফ্রেগমেন্ট বলি। যখন খণ্ড খণ্ড তৈরি করা হয়, আমরা এটিকে চাইল্ডফ্রেগমেন্টএনিমেশন ম্যানেজারে যুক্ত করি এবং এটি নষ্ট হয়ে গেলে এটি সরিয়ে ফেলি। আপনি এটি অনাচ / ডিটাচ, বা অনুক্রমের সাথে অন্যান্য মিলের পদ্ধতিগুলি করতে পারেন। ভিউ তৈরি করুন / ধ্বংস করুন বাছাই করার জন্য আমার যুক্তিটি হ'ল কারণ যদি কোনও খণ্ডের কোনও ভিউ না থাকে তবে আমি এটি চালিয়ে যাওয়া অ্যানিমেট করার বিষয়ে চিন্তা করি না। এই দ্রষ্টব্যটি ভিউপ্যাজারগুলির সাথে আরও ভালভাবে কাজ করা উচিত যা খণ্ডগুলি ব্যবহার করে কারণ আপনি প্রতিটি ফ্রেমমেন্টের উপর নজর রাখবেন না যে একটি ফ্রেগমেন্টপাগারএডাপ্টার রাখে, তবে কেবল 3।

public abstract class BaseFragment extends Fragment {

@Override
public  View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    Fragment parent = getParentFragment();
    if (parent != null) {
        ChildFragmentAnimationManager.instance().putChild(parent, this);
    }

    return super.onCreateView(inflater, container, savedInstanceState);
}

@Override
public void onDestroyView() {
    Fragment parent = getParentFragment();
    if (parent != null) {
        ChildFragmentAnimationManager.instance().removeChild(parent, this);
    }

    super.onDestroyView();
}

}

এখন যেহেতু আপনার সমস্ত টুকরোগুলি পিতামণ্ডিত খণ্ডের দ্বারা মেমরিতে সংরক্ষণ করা হয়েছে, আপনি সেগুলিতে এটিকে এনিমেট করতে পারেন এবং আপনার সন্তানের খণ্ডগুলি অদৃশ্য হয়ে যাবে না।

FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ChildFragmentAnimationManager.instance().animate(ft, ReaderFragment.this)
                    .setCustomAnimations(R.anim.up_in, R.anim.up_out, R.anim.down_in, R.anim.down_out)
                    .replace(R.id.container, f)
                    .addToBackStack(null)
                    .commit();

এছাড়াও, ঠিক আপনার কাছে এটি রয়েছে, এখানে কোনও_আনিম.এক্সএমএল ফাইল রয়েছে যা আপনার রেজ / আনিম ফোল্ডারে যায়:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator">
    <translate android:fromXDelta="0" android:toXDelta="0"
        android:duration="1000" />
</set>

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


1

আমার মনে হয় লুকসপ্রোগের পরামর্শ অনুসারে বিটম্যাপে বর্তমান টুকরো টুকরো টুকরো করার চেয়ে আমি এই সমস্যার আরও ভাল সমাধান পেয়েছি।

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

আমাদের FragmentAএবং FragmentBউভয় উপ টুকরা সহ কল্পনা করুন । এখন আপনি যখন সাধারণত করবেন:

getSupportFragmentManager()
  .beginTransaction()
  .setCustomAnimations(anim1, anim2, anim1, anim2)
  .add(R.id.fragmentHolder, new FragmentB())
  .remove(fragmentA)    <-------------------------------------------
  .addToBackStack(null)
  .commit()

পরিবর্তে আপনি না

getSupportFragmentManager()
  .beginTransaction()
  .setCustomAnimations(anim1, anim2, anim1, anim2)
  .add(R.id.fragmentHolder, new FragmentB())
  .hide(fragmentA)    <---------------------------------------------
  .addToBackStack(null)
  .commit()

fragmentA.removeMe = true;

খণ্ডটি বাস্তবায়নের জন্য এখন:

public class BaseFragment extends Fragment {

    protected Boolean detachMe = false;
    protected Boolean removeMe = false;

    @Override
    public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
        if (nextAnim == 0) {
            if (!enter) {
                onExit();
            }

            return null;
        }

        Animation animation = AnimationUtils.loadAnimation(getActivity(), nextAnim);
        assert animation != null;

        if (!enter) {
            animation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    onExit();
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }
            });
        }

        return animation;
    }

    private void onExit() {
        if (!detachMe && !removeMe) {
            return;
        }

        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        if (detachMe) {
            fragmentTransaction.detach(this);
            detachMe = false;
        } else if (removeMe) {
            fragmentTransaction.remove(this);
            removeMe = false;
        }
        fragmentTransaction.commit();
    }
}

পপব্যাকস্ট্যাকের কারণে কোনও ত্রুটি ঘটবে না কারণ এটি কোনও বিভাজন প্রদর্শন করার চেষ্টা করছে যা আলাদা করা হয়েছে?
আলেকজান্দ্রে

1

আমি মানচিত্র খণ্ডের সাথে একই সমস্যা ছিল I এটি এতে থাকা খণ্ডটির প্রস্থান অ্যানিমেশনের সময় অদৃশ্য হয়ে যায়। কাজের মাপসইটি হ'ল চাইল্ড ম্যাপ টুকরাটির জন্য অ্যানিমেশন যুক্ত করা যা প্যারেন্ট খণ্ডের প্রস্থান অ্যানিমেশনের সময় এটি দৃশ্যমান রাখবে। শিশু খণ্ডটির অ্যানিমেশন তার সময়কালের সময়কালে এটির আলফাটি 100% এ রাখছে।

অ্যানিমেশন: রেস / অ্যানিম্যাটর / কিপ_সিল্ড_ফ্রেগমেন্ট.এক্সএমএল

<?xml version="1.0" encoding="utf-8"?>    
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:propertyName="alpha"
        android:valueFrom="1.0"
        android:valueTo="1.0"
        android:duration="@integer/keep_child_fragment_animation_duration" />
</set>

অ্যানিমেশনটি তখন প্রয়োগ করা হয় যখন মানচিত্রের খণ্ডটি পিতামণ্ডুল খণ্ডে যুক্ত করা হয়।

পিতামাতার খণ্ড

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.map_parent_fragment, container, false);

    MapFragment mapFragment =  MapFragment.newInstance();

    getChildFragmentManager().beginTransaction()
            .setCustomAnimations(R.animator.keep_child_fragment, 0, 0, 0)
            .add(R.id.map, mapFragment)
            .commit();

    return view;
}

অবশেষে, সন্তানের খণ্ড অ্যানিমেশনটির সময়কাল একটি উত্স ফাইলে সেট করা আছে।

মান / integers.xml

<resources>
  <integer name="keep_child_fragment_animation_duration">500</integer>
</resources>

0

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

এখানে কোড সহ উদাহরণ।

View.OnClickListener() {//this is from custom button but you can listen for back button pressed
            @Override
            public void onClick(View v) {
                getChildFragmentManager().popBackStack();
                //and here we can manage other fragment operations 
            }
        });

  Fragment fr = MyNeastedFragment.newInstance(product);

  getChildFragmentManager()
          .beginTransaction()
                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE)
                .replace(R.neasted_fragment_container, fr)
                .addToBackStack("Neasted Fragment")
                .commit();

0

আমি সম্প্রতি আমার প্রশ্নে এই সমস্যায় পড়েছি: নেস্টেড টুকরোগুলি ভুলভাবে স্থানান্তরিত হচ্ছে

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

একটি উদাহরণ প্রকল্প এখানে দেখা যাবে: https://github.com/zafrani/ নেস্টেড ফ্রেমমেন্ট ট্রান্সশিশন

প্রভাবটির একটি জিআইএফ এখানে দেখা যায়: https://imgur.com/94 অ্যাভ্রডব্লু 4

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

সমাধানের সিংহভাগ আমার বেসফ্রেগমেন্টের (আমার বাচ্চাদের এবং পিতামাতার টুকরো দ্বারা প্রসারিত টুকরো) অনক্রিয়েট অ্যানিমেটার ফাংশনটিতে রয়েছে যা দেখতে এটির মতো দেখায়:

   override fun onCreateAnimator(transit: Int, enter: Boolean, nextAnim: Int): Animator {
    if (isConfigChange) {
        resetStates()
        return nothingAnim()
    }

    if (parentFragment is ParentFragment) {
        if ((parentFragment as BaseFragment).isPopping) {
            return nothingAnim()
        }
    }

    if (parentFragment != null && parentFragment.isRemoving) {
        return nothingAnim()
    }

    if (enter) {
        if (isPopping) {
            resetStates()
            return pushAnim()
        }
        if (isSuppressing) {
            resetStates()
            return nothingAnim()
        }
        return enterAnim()
    }

    if (isPopping) {
        resetStates()
        return popAnim()
    }

    if (isSuppressing) {
        resetStates()
        return nothingAnim()
    }

    return exitAnim()
}

ক্রিয়াকলাপ এবং অভিভাবক খণ্ডগুলি এই বুলিয়ানগুলির রাজ্যগুলি নির্ধারণের জন্য দায়বদ্ধ। আমার উদাহরণ প্রকল্প থেকে কীভাবে এবং কোথায় তা দেখা সহজ।

আমি আমার উদাহরণে সমর্থনের টুকরোগুলি ব্যবহার করছি না, তবে তাদের এবং তাদের অনক্রিয়েট অ্যানিমেশন ফাংশনটিতে একই যুক্তি ব্যবহার করা যেতে পারে


0

এই সমস্যাটি সমাধানের একটি সহজ উপায় হ'ল Fragmentস্ট্যান্ডার্ড লাইব্রেরি খণ্ড বিভাগের পরিবর্তে এই পাঠাগার থেকে শ্রেণিটি ব্যবহার করুন :

https://github.com/marksalpeter/contract-fragment

পার্শ্ব নোট হিসাবে, প্যাকেজটিতে একটি দরকারী প্রতিনিধি প্যাটার্নও রয়েছে ContractFragmentযা আপনাকে পিতামাতাদের এবং সন্তানের খণ্ডের সম্পর্কের জন্য আপনার অ্যাপ্লিকেশন তৈরির জন্য দরকারী বলে মনে করতে পারে।


0

@ কেকপপকের উপরের উত্তর থেকে,

আপনার যদি ক্রিয়াকলাপ-> টুকরা-> খণ্ডগুলি থাকে (একাধিক স্ট্যাকিং, নীচে সহায়তা করে), সেরা উত্তরের আইএমএইচওতে একটি ছোটখাটো সম্পাদনা।

public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {

    final Fragment parent = getParentFragment();

    Fragment parentOfParent = null;

    if( parent!=null ) {
        parentOfParent = parent.getParentFragment();
    }

    if( !enter && parent != null && parentOfParent!=null && parentOfParent.isRemoving()){
        Animation doNothingAnim = new AlphaAnimation(1, 1);
        doNothingAnim.setDuration(getNextAnimationDuration(parent, DEFAULT_CHILD_ANIMATION_DURATION));
        return doNothingAnim;
    } else
    if (!enter && parent != null && parent.isRemoving()) {
        // This is a workaround for the bug where child fragments disappear when
        // the parent is removed (as all children are first removed from the parent)
        // See https://code.google.com/p/android/issues/detail?id=55228
        Animation doNothingAnim = new AlphaAnimation(1, 1);
        doNothingAnim.setDuration(getNextAnimationDuration(parent, DEFAULT_CHILD_ANIMATION_DURATION));
        return doNothingAnim;
    } else {
        return super.onCreateAnimation(transit, enter, nextAnim);
    }
}

0

আমার সমস্যাটি পিতামাতার টুকরো অপসারণ (ft.remove (খণ্ড)) এ ছিল, শিশু অ্যানিমেশনগুলি হচ্ছিল না।

মূল সমস্যাটি হ'ল শিশু খণ্ডগুলি অবিলম্বে অ্যানিমেশন থেকে বেরিয়ে আসা পিতা-মাতার টুকরোতে প্রাইভারকে অবিচ্ছিন্নভাবে অগ্রাহ্য করে।

শিশু টুকরোগুলি কাস্টম অ্যানিমেশনগুলি পিতা-মাতা খন্ড অপসারণের সময় কার্যকর হয় না

অন্যরা যেমন মেনে চলেছে, প্যারেন্টটি অপসারণের আগে প্যারেন্ট (এবং শিশু নয়) লুকিয়ে রাখার উপায়।

            val ft = fragmentManager?.beginTransaction()
            ft?.setCustomAnimations(R.anim.enter_from_right,
                    R.anim.exit_to_right)
            if (parentFragment.isHidden()) {
                ft?.show(vehicleModule)
            } else {
                ft?.hide(vehicleModule)
            }
            ft?.commit()

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

BTW আপনার সন্তানের খণ্ডে কাস্টম অ্যানিমেশনগুলির প্রয়োজন নেই, কারণ তারা পিতামাতার অ্যানিমেশনগুলির উত্তরাধিকারী হবে।



0

পুরানো থ্রেড, তবে যদি কেউ এখানে হোঁচট খায় তবে:

উপরের সমস্ত পন্থা আমার জন্য অত্যন্ত অপ্রয়োজনীয় বোধ করে, বিটম্যাপ সমাধানটি খুব নোংরা এবং অ অভিনেতা; অন্যটিগুলির মধ্যে শিশুদের টুকরো তৈরি করা প্রশ্নে শিশু খণ্ড তৈরি করতে ব্যবহৃত লেনদেনে ব্যবহৃত ট্রানজিশনের সময়কাল সম্পর্কে জানতে শিশুর টুকরোগুলি প্রয়োজন। আমার দৃষ্টিতে আরও ভাল সমাধান আমি নিম্নলিখিতগুলির মতো কিছু:

val currentFragment = supportFragmentManager.findFragmentByTag(TAG)
val transaction = supportFragmentManager
    .beginTransaction()
    .setCustomAnimations(anim1, anim2, anim1, anim2)
    .add(R.id.fragmentHolder, FragmentB(), TAG)
if (currentFragment != null) {
    transaction.hide(currentFragment).commit()
    Handler().postDelayed({
        supportFragmentManager.beginTransaction().remove(currentFragment).commit()
    }, DURATION_OF_ANIM)
} else {
    transaction.commit()
}

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

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