Foldables জন্য ডিজাইনিং

ConstraintLayout 2.1 রিলিজে, ভাগ করা যায় এমন ডিভাইসগুলি পরিচালনা করতে সাহায্য করার জন্য বেশ কিছু বৈশিষ্ট্য যোগ করা হয়েছে, যার মধ্যে রয়েছে SharedValues ​​, ReactiveGuide , এবং MotionLayout এর সাথে অ্যানিমেশনের জন্য উন্নত সমর্থন।

ভাগ করা মান

আমরা ConstraintLayout এ রানটাইম মান ইনজেক্ট করার জন্য একটি নতুন প্রক্রিয়া যোগ করেছি - এটি সিস্টেম-ব্যাপী মানগুলির জন্য ব্যবহার করার উদ্দেশ্যে, কারণ ConstraintLayout এর সমস্ত উদাহরণ মান অ্যাক্সেস করতে সক্ষম।

ভাঁজযোগ্য ডিভাইসের প্রেক্ষাপটে, আমরা রানটাইমে ভাঁজের অবস্থান ইনজেক্ট করতে এই প্রক্রিয়াটি ব্যবহার করতে পারি:

কোটলিন

ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold)

জাভা

ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold);

একটি কাস্টম সাহায্যকারীতে, আপনি যেকোনো পরিবর্তনের জন্য একজন শ্রোতা যোগ করে শেয়ার করা মানগুলি অ্যাক্সেস করতে পারেন:

কোটলিন

val sharedValues: SharedValues = ConstraintLayout.getSharedValues()
sharedValues.addListener(mAttributeId, this)

জাভা

SharedValues sharedValues = ConstraintLayout.getSharedValues();
sharedValues.addListener(mAttributeId, this);

কিভাবে আমরা Jetpack WindowManager লাইব্রেরি ব্যবহার করে ভাঁজের অবস্থান ক্যাপচার করি এবং ConstraintLayout এ অবস্থানটি ইনজেকশন করি তা দেখতে আপনি FoldableExperiments উদাহরণটি দেখতে পারেন।

কোটলিন

inner class StateContainer : Consumer<WindowLayoutInfo> {

    override fun accept(newLayoutInfo: WindowLayoutInfo) {

        // Add views that represent display features
        for (displayFeature in newLayoutInfo.displayFeatures) {
            val foldFeature = displayFeature as? FoldingFeature
            if (foldFeature != null) {
                if (foldFeature.isSeparating &&
                    foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
                ) {
                    // The foldable device is in tabletop mode
                    val fold = foldPosition(motionLayout, foldFeature)
                    ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold)
                } else {
                    ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0);
                }
            }
        }
    }
}

জাভা

class StateContainer implements Consumer<WindowLayoutInfo> {

    @Override
    public void accept(WindowLayoutInfo newLayoutInfo) {

        // Add views that represent display features
        for (DisplayFeature displayFeature : newLayoutInfo.getDisplayFeatures()) {
            if (displayFeature instanceof FoldingFeature) {
                FoldingFeature foldFeature = (FoldingFeature)displayFeature;
                if (foldFeature.isSeparating() &&
                    foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL
                ) {
                    // The foldable device is in tabletop mode
                    int fold = foldPosition(motionLayout, foldFeature);
                    ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold);
                } else {
                    ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0);
                }
            }
        }
    }
}

fireNewValue() প্রথম প্যারামিটার হিসাবে মান এবং দ্বিতীয় প্যারামিটার হিসাবে ইনজেক্ট করার জন্য মান উপস্থাপন করে একটি ID নেয়।

ReactiveGuide

একটি লেআউটে SharedValue সুবিধা নেওয়ার একটি উপায়, কোনো কোড না লিখেই, হল ReactiveGuide সাহায্যকারী ব্যবহার করা। এটি লিঙ্ক করা SharedValue অনুযায়ী একটি অনুভূমিক বা উল্লম্ব নির্দেশিকা স্থাপন করবে।

    <androidx.constraintlayout.widget.ReactiveGuide
        android:id="@+id/fold"
        app:reactiveGuide_valueId="@id/fold"
        android:orientation="horizontal" />

তারপরে এটি একটি সাধারণ নির্দেশিকা সহ আপনি হিসাবে ব্যবহার করা যেতে পারে।

Foldables জন্য MotionLayout

আমরা 2.1-এ MotionLayout এ বেশ কিছু বৈশিষ্ট্য যুক্ত করেছি যা অবস্থার মরফিং করতে সাহায্য করে - কিছু বিশেষভাবে ফোল্ডেবলের জন্য দরকারী, কারণ আমাদের সাধারণত বিভিন্ন সম্ভাব্য লেআউটের মধ্যে অ্যানিমেটিং পরিচালনা করতে হয়।

ফোল্ডেবলের জন্য দুটি পদ্ধতি উপলব্ধ রয়েছে:

  • রানটাইমে, ভাঁজ দেখানো বা লুকানোর জন্য আপনার বর্তমান লেআউট ( ConstraintSet ) আপডেট করুন।
  • আপনি সমর্থন করতে চান এমন প্রতিটি ভাঁজযোগ্য অবস্থার জন্য একটি পৃথক ConstraintSet ব্যবহার করুন ( closed , folded বা fully open )।

একটি ConstraintSet অ্যানিমেটিং

MotionLayout এ ফাংশন updateStateAnimate() 2.1 রিলিজে যোগ করা হয়েছে:

কোটলিন

fun updateStateAnimate(stateId: Int, set: ConstraintSet, duration: Int)

জাভা

void updateStateAnimate(int stateId, ConstraintSet set, int duration);

একটি তাত্ক্ষণিক আপডেট করার পরিবর্তে একটি প্রদত্ত ConstraintSet আপডেট করার সময় এই ফাংশনটি স্বয়ংক্রিয়ভাবে পরিবর্তনগুলিকে অ্যানিমেট করবে (যা আপনি updateState(stateId, constraintset) এর সাথে করতে পারেন)। এটি আপনাকে পরিবর্তনের উপর নির্ভর করে আপনার UI আপডেট করতে দেয়, যেমন আপনি কোন ভাঁজযোগ্য অবস্থায় আছেন।

একটি MotionLayout ভিতরে ReactiveGuide

ReactiveGuide একটি MotionLayout ভিতরে ব্যবহার করার সময় দুটি দরকারী বৈশিষ্ট্য সমর্থন করে:

  • app:reactiveGuide_animateChange="true|false"

  • app:reactiveGuide_applyToAllConstraintSets="true|false"

প্রথমটি বর্তমান ConstraintSet সংশোধন করবে এবং পরিবর্তনটিকে স্বয়ংক্রিয়ভাবে অ্যানিমেট করবে। দ্বিতীয়টি MotionLayout এর সমস্ত ConstraintSetReactiveGuide অবস্থানের নতুন মান প্রয়োগ করবে। ফোল্ডেবলের জন্য একটি সাধারণ পদ্ধতি হল ভাঁজ অবস্থানের প্রতিনিধিত্বকারী একটি ReactiveGuide ব্যবহার করা, ReactiveGuide এর সাথে সম্পর্কিত আপনার লেআউট উপাদানগুলি সেট আপ করা।

ভাঁজযোগ্য অবস্থার প্রতিনিধিত্ব করতে একাধিক ConstraintSet ব্যবহার করে

বর্তমান MotionLayout অবস্থা আপডেট করার পরিবর্তে, ফোল্ডেবল সমর্থন করার জন্য আপনার UI স্থপতি করার আরেকটি উপায় হল নির্দিষ্ট পৃথক স্টেট তৈরি করা ( closed , folded এবং fully open সহ)।

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

এই পদ্ধতির সাহায্যে, আপনার DeviceState শ্রোতাদের মধ্যে, আপনি MotionLayout.transitionToState(stateId) পদ্ধতির মাধ্যমে নির্দিষ্ট রাজ্যে স্থানান্তরের জন্য MotionLayout নির্দেশ দেবেন।