কার্ড ডিজাইন

GDK ব্যবহার করার সময় কীভাবে গ্লাস শৈলী অনুসরণ করা যায় এবং সাধারণ UI সর্বোত্তম অনুশীলনগুলি প্রয়োগ করা যায় তা এই নথিতে দেওয়া হয়েছে।

গ্লাস থিম

গ্লাস আপনার গ্লাসওয়্যারে একটি আদর্শ থিম প্রয়োগ করে, তাই এটি বাকি ব্যবহারকারী ইন্টারফেসের সাথে সামঞ্জস্যপূর্ণ থাকে। থিমটির নিম্নলিখিত বৈশিষ্ট্য রয়েছে:

  • রোবোটো টাইপফেস ব্যবহার করে
  • কোনো স্ট্যাটাস বার বা অ্যাকশন বার ছাড়াই ক্রিয়াকলাপগুলিকে পূর্ণ-স্ক্রীনে দেখায়
  • কঠিন, কালো পটভূমি প্রযোজ্য

গ্লাস থিম প্রয়োগ করতে, আপনার Android ম্যানিফেস্টে একটি থিম ঘোষণা করবেন না৷

যদি আপনার গ্লাসওয়্যারের অংশগুলির জন্য একটি কাস্টম শৈলী থাকে এবং অন্য সব কিছুর জন্য ডিফল্ট গ্লাস থিম চান, তাহলে parent বৈশিষ্ট্য সহ Theme.DeviceDefault থেকে উত্তরাধিকারী হন:

<resources>
    <style name="CustomTheme" parent="@android:style/Theme.DeviceDefault">
        <!-- Theme customization goes here. -->
    </style>
</resources>

থিম তৈরির বিষয়ে আরও তথ্যের জন্য শৈলী এবং থিমগুলির উপর Android বিকাশকারী নির্দেশিকা দেখুন৷

কাচের স্টাইলযুক্ত কার্ড

CardBuilder ক্লাস বৈশিষ্ট্যের একটি সেট দিয়ে সুগঠিত কার্ড তৈরি করে। CardBuilder.Layout দ্বারা প্রদত্ত লেআউটগুলি ব্যবহার করুন৷ যখনই সম্ভব তখন লেআউট করুন যাতে আপনার সামগ্রীটি গ্লাসের অন্যান্য সামগ্রীর মতো দেখতে এবং অনুভূত হয়৷

CardBuilder ব্যবহার করতে:

  1. CardBuilder এর একটি উদাহরণ তৈরি করুন, এটি CardBuilder.Layout থেকে আপনার পছন্দসই বিন্যাস প্রদান করুন।
  2. কার্ডের বৈশিষ্ট্যগুলি সেট করুন, যেমন পাঠ্য, পাদটীকা এবং টাইমস্ট্যাম্প৷
  3. কার্ডটিকে অ্যান্ড্রয়েড View রূপান্তর করতে CardBuilder.getView() কল করুন, অথবা এটিকে একটি RemoteViews অবজেক্টে রূপান্তর করতে CardBuilder.getRemoteViews() কল করুন৷
  4. আপনার ক্রিয়াকলাপ, লেআউটে বা একটি CardScrollView View ব্যবহার করুন বা LiveCard RemoteViews ব্যবহার করুন।

সাধারণ UI বৈশিষ্ট্য

CardBuilder দ্বারা প্রদত্ত অনেকগুলি লেআউট নীচে বর্ণিত সাধারণ ব্যবহারকারী ইন্টারফেস বৈশিষ্ট্যগুলিকে সমর্থন করে৷ প্রতিটি ধরনের কার্ড দ্বারা সমর্থিত বৈশিষ্ট্যগুলির একটি তালিকার জন্য CardBuilder.Layout এ পৃথক বিন্যাসের ডকুমেন্টেশন দেখুন।

অ্যাট্রিবিউশন আইকন

অ্যাট্রিবিউশন আইকন হল একটি ঐচ্ছিক 36 × 36 পিক্সেল আইকন যা একটি কার্ডের নীচে-ডানদিকে এবং টাইমস্ট্যাম্পের ডানদিকে প্রদর্শিত হয়৷ আপনার অ্যাপ্লিকেশন সনাক্ত করতে CardBuilder.setAttributionIcon() এ কল করে এই আইকনটি সেট করুন, বিশেষ করে লাইভ কার্ডে যাতে একজন ব্যবহারকারী দ্রুত তাকাতে পারে এবং সেই কার্ডের তথ্যের উৎস দেখতে পারে৷

স্ট্যাক সূচক

CardBuilder.showStackIndicator() দ্বারা নিয়ন্ত্রিত স্ট্যাক নির্দেশক হল একটি কোণার ভাঁজ যা একটি কার্ডের উপরের-ডানদিকে প্রদর্শিত হয়। এটি একটি ভিজ্যুয়াল সূচক হিসাবে ব্যবহার করুন যে আপনার কার্ডটি অন্যান্য কার্ডগুলির একটি বান্ডিল প্রতিনিধিত্ব করে যা ব্যবহারকারী সরাসরি ট্যাপ করতে পারে।

View view = new CardBuilder(context, CardBuilder.Layout.TEXT)
    .setText("A stack indicator can be added to the corner of a card...")
    .setAttributionIcon(R.drawable.ic_smile)
    .showStackIndicator(true)
    .getView();

বিন্যাস

নিম্নলিখিত উদাহরণগুলি CardBuilder ব্যবহার করে উপলব্ধ লেআউটগুলি দেখায়৷

TEXT এবং TEXT_FIXED

CardBuilder.Layout.TEXT লেআউট ব্যাকগ্রাউন্ডে একটি ঐচ্ছিক ইমেজ মোজাইক সহ ফুল-ব্লিড টেক্সট দেখায়। পাঠ্যটি গতিশীলভাবে উপলব্ধ স্থানের সাথে সর্বোত্তম ফিট করার জন্য আকার পরিবর্তন করে। CardBuilder.Layout.TEXT_FIXED অনুরূপ কিন্তু এর পাঠ্যকে একটি ছোট আকারে সংশোধন করে৷

View view1 = new CardBuilder(context, CardBuilder.Layout.TEXT)
    .setText("This is the TEXT layout. The text size will adjust dynamically.")
    .setFootnote("This is the footnote")
    .setTimestamp("just now")
    .getView();
View view2 = new CardBuilder(context, CardBuilder.Layout.TEXT)
    .setText("You can also add images to the background of a TEXT card.")
    .setFootnote("This is the footnote")
    .setTimestamp("just now")
    .addImage(R.drawable.image1)
    .addImage(R.drawable.image2)
    .addImage(R.drawable.image3)
    .addImage(R.drawable.image4)
    .addImage(R.drawable.image5)
    .getView();
View view3 = new CardBuilder(context, CardBuilder.Layout.TEXT_FIXED)
    .setText("This is the TEXT_FIXED layout. The text size is always the same.")
    .setFootnote("This is the footnote")
    .setTimestamp("just now")
    .getView();

COLUMNS এবং COLUMNS_FIXED

CardBuilder.Layout.COLUMNS লেআউট কার্ডের বাম দিকে একটি ইমেজ মোজাইক বা আইকন এবং ডান পাশে টেক্সট দেখায়। পাঠ্যটি গতিশীল আকারে উপলব্ধ স্থানের সাথে সর্বোত্তম ফিট করার জন্য। পাঠ্যের আকার ঠিক রাখতে, CardBuilder.Layout.COLUMNS_FIXED ব্যবহার করুন।

View view1 = new CardBuilder(context, CardBuilder.Layout.COLUMNS)
    .setText("This is the COLUMNS layout with dynamic text.")
    .setFootnote("This is the footnote")
    .setTimestamp("just now")
    .addImage(R.drawable.image1)
    .addImage(R.drawable.image2)
    .addImage(R.drawable.image3)
    .addImage(R.drawable.image4)
    .addImage(R.drawable.image5)
    .getView();
View view2 = new CardBuilder(context, CardBuilder.Layout.COLUMNS)
    .setText("You can even put a centered icon on a COLUMNS card instead of a mosaic.")
    .setFootnote("This is the footnote")
    .setTimestamp("just now")
    .setIcon(R.drawable.ic_wifi)
    .getView();
View view3 = new CardBuilder(context, CardBuilder.Layout.COLUMNS_FIXED)
    .setText("This is the COLUMNS_FIXED layout. The text size is always the same.")
    .setFootnote("This is the footnote")
    .setTimestamp("just now")
    .addImage(R.drawable.image1)
    .addImage(R.drawable.image2)
    .addImage(R.drawable.image3)
    .addImage(R.drawable.image4)
    .addImage(R.drawable.image5)
    .getView();

CAPTION

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

চিত্র 1 : ( photoeverywhere.co.uk দ্বারা পটভূমি চিত্র , ক্রপ করা হয়েছে)
View view1 = new CardBuilder(context, CardBuilder.Layout.CAPTION)
    .setText("The caption layout.")
    .setFootnote("This is the footnote")
    .setTimestamp("just now")
    .addImage(R.drawable.beach)
    .setAttributionIcon(R.drawable.ic_smile)
    .getView();

View view2 = new CardBuilder(context, CardBuilder.Layout.CAPTION)
    .setText("The caption layout with an icon.")
    .setFootnote("This is the footnote")
    .setTimestamp("just now")
    .addImage(R.drawable.beach)
    .setIcon(R.drawable.ic_avatar)
    .setAttributionIcon(R.drawable.ic_smile)
    .getView();

TITLE

CardBuilder.Layout.TITLE লেআউটের পটভূমিতে একটি কেন্দ্রীভূত শিরোনাম এবং কার্ডের নীচে ঐচ্ছিক আইকন সহ একটি চিত্র মোজাইক রয়েছে৷ এই লেআউটটি প্রায়ই পরিচিতিগুলিকে উপস্থাপন করতে বা লক্ষ্যগুলি ভাগ করতে ব্যবহৃত হয়। পাদটীকা এবং টাইমস্ট্যাম্প এই লেআউটে সমর্থিত নয়।

View view = new CardBuilder(context, CardBuilder.Layout.TITLE)
    .setText("TITLE Card")
    .setIcon(R.drawable.ic_phone)
    .addImage(R.drawable.beach)
    .getView();

AUTHOR

একটি বার্তা বা কথোপকথন প্রদর্শন করতে CardBuilder.Layout.AUTHOR লেআউটটি ব্যবহার করুন যেখানে ফোকাস লেখকের দিকে থাকে৷ এটি পটভূমিতে একটি চিত্র মোজাইক, লেখকের অবতার হিসাবে ব্যবহৃত একটি আইকন এবং একটি শিরোনাম এবং উপশিরোনাম সমর্থন করে যেখানে আপনি সনাক্তকারী তথ্য তালিকাভুক্ত করতে পারেন।

View view = new CardBuilder(context, CardBuilder.Layout.AUTHOR)
    .setText("The AUTHOR layout lets you display a message or conversation "
            + " with a focus on the author.")
    .setIcon(R.drawable.ic_avatar)
    .setHeading("Joe Lastname")
    .setSubheading("Mountain View, California")
    .setFootnote("This is the footnote")
    .setTimestamp("just now")
    .getView();

CardBuilder.Layout.MENU লেআউটটি একটি সাধারণ গ্লাস মেনুর মতো দেখায়। এটিতে একটি কেন্দ্রীভূত আইকন এবং শিরোনাম এবং একটি ঐচ্ছিক পাদটীকা রয়েছে। নিশ্চিতকরণ স্ক্রিনের জন্য এই লেআউটটি ব্যবহার করুন (উদাহরণস্বরূপ, ব্যবহারকারী একটি মেনু আইটেম নির্বাচন করার পরে "মুছে ফেলা" থেকে "মুছে ফেলা" এ রূপান্তর করা)। আপনার যদি সত্যিকারের মেনুর প্রয়োজন হয় তবে আপনার পরিবর্তে একটি আদর্শ বিকল্প মেনু ব্যবহার করা উচিত।

View view = new CardBuilder(context, CardBuilder.Layout.MENU)
    .setText("MENU layout")
    .setIcon(R.drawable.ic_phone)
    .setFootnote("Optional menu description")
    .getView();

EMBED_INSIDE

CardBuilder.Layout.EMBED_INSIDE লেআউট স্ট্যান্ডার্ড গ্লাস কার্ড টেমপ্লেটে আপনার নিজস্ব ডিজাইনের একটি কাস্টম লেআউট XML এম্বেড করে। এটি আপনাকে আপনার অ্যাপ্লিকেশনের জন্য একটি কাস্টম UI ডিজাইন করতে দেয় তবে এখনও কার্ডের পাদটীকা, টাইমস্ট্যাম্প, অ্যাট্রিবিউশন আইকন এবং স্ট্যাক নির্দেশকের সঠিক স্থান নির্ধারণ করতে দেয় যদি সেগুলি প্রয়োজন হয়৷

CardBuilder.getView() কল করার পরে, আপনার এমবেড করা লেআউটের ভিউ অ্যাক্সেস করতে ফলাফলে findViewById() ব্যবহার করুন। একইভাবে, আপনি যদি CardBuilder.getRemoteViews() কল করেন, তাহলে আপনি তাদের আইডিগুলিকে সরাসরি RemoteViews সেটার পদ্ধতিতে পাস করে আপনার এমবেড করা লেআউটের ভিউ ম্যানিপুলেট করতে পারেন।

View view = new CardBuilder(context, CardBuilder.Layout.EMBED_INSIDE)
    .setEmbeddedLayout(R.layout.food_table)
    .setFootnote("Foods you tracked")
    .setTimestamp("today")
    .getView();
TextView textView1 = (TextView) view.findViewById(R.id.text_view_1);
textView1.setText("Water");
// ...and so on

আরও বিস্তারিত উদাহরণের জন্য, GitHub ApiDemo প্রকল্পটি দেখুন।

ALERT

CardBuilder.Layout.ALERT লেআউটে একটি প্রাথমিক বার্তা এবং পাদটীকা সহ একটি বড় কেন্দ্রীভূত আইকন রয়েছে৷ আপনার গ্লাসওয়্যারে একটি গুরুত্বপূর্ণ তথ্যমূলক বার্তা, সতর্কতা বা ত্রুটি দেখাতে Dialog এই লেআউটটি ব্যবহার করুন।

নিম্নলিখিত উদাহরণটি AlertDialog এর বাস্তবায়ন দেখায় এবং কার্ডটি খারিজ করে এবং ব্যবহারকারী কার্ডে ট্যাপ করলে WiFi সেটিংস খোলে:

  1. Dialog প্রসারিত করে এমন একটি ক্লাস তৈরি করুন।
  2. CardBuilder.Layout.ALERT লেআউট দিয়ে CardBuilder ব্যবহার করে কার্ডটি তৈরি করুন এবং তারপর এই কার্ডের সাথে বিষয়বস্তু ভিউ সেট করুন৷
  3. (ঐচ্ছিক) এই কার্ডে ব্যবহারকারীর অঙ্গভঙ্গি পরিচালনা করার জন্য একটি GestureDetector তৈরি করুন।

    public class AlertDialog extends Dialog {
    
        private final DialogInterface.OnClickListener mOnClickListener;
        private final AudioManager mAudioManager;
        private final GestureDetector mGestureDetector;
    
        /**
         * Handles the tap gesture to call the dialog's
         * onClickListener if one is provided.
         */
        private final GestureDetector.BaseListener mBaseListener =
            new GestureDetector.BaseListener() {
    
            @Override
            public boolean onGesture(Gesture gesture) {
                if (gesture == Gesture.TAP) {
                    mAudioManager.playSoundEffect(Sounds.TAP);
                    if (mOnClickListener != null) {
                        // Since Glass dialogs do not have buttons,
                        // the index passed to onClick is always 0.
                        mOnClickListener.onClick(AlertDialog.this, 0);
                    }
                    return true;
                }
                return false;
            }
        };
    
        public AlertDialog(Context context, int iconResId,
                           int textResId, int footnoteResId,
                           DialogInterface.OnClickListener onClickListener) {
            super(context);
    
            mOnClickListener = onClickListener;
            mAudioManager =
                (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            mGestureDetector =
                new GestureDetector(context).setBaseListener(mBaseListener);
    
            setContentView(new CardBuilder(context, CardBuilder.Layout.ALERT)
                    .setIcon(iconResId)
                    .setText(textResId)
                    .setFootnote(footnoteResId)
                    .getView());
        }
    
        /** Overridden to let the gesture detector handle a possible tap event. */
        @Override
        public boolean onGenericMotionEvent(MotionEvent event) {
            return mGestureDetector.onMotionEvent(event)
                || super.onGenericMotionEvent(event);
        }
    }
    
  4. (ঐচ্ছিক) আপনার কার্যকলাপে, ব্যবহারকারী ট্যাপ করলে যেকোন অতিরিক্ত প্রবাহ পরিচালনা করতে একটি OnClickListener প্রয়োগ করুন। WiFi এর মতো সেটিংস কার্যক্রম শুরু করার বিষয়ে আরও তথ্যের জন্য, শুরু সেটিংস দেখুন।

  5. সতর্কতা কার্ড প্রদর্শন করতে AlertDialog কনস্ট্রাক্টরকে কল করুন।

    public class MyActivity extends Activity {
        ...
        private final DialogInterface.OnClickListener mOnClickListener =
                new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int button) {
                            // Open WiFi Settings
                            startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
                        }
                };
    
        @Override
        protected void onCreate(Bundle bundle) {
            ...
    
            new AlertDialog(context, R.drawable.ic_cloud_sad_150, R.string.alert_text,
                R.string.alert_footnote_text, mOnClickListener).show();
    
            ...
        }
    }
    

XML লেআউট

এখানে দুটি মৌলিক কার্ড লেআউট রয়েছে যা আপনি ব্যবহার করতে পারেন যদি কার্ডবিল্ডার ক্লাস আপনার চাহিদা পূরণ না করে।

প্রধান বিন্যাস

এই লেআউটটি একটি কার্ডের জন্য স্ট্যান্ডার্ড প্যাডিং এবং ফুটার সংজ্ঞায়িত করে। খালি RelativeLayout আপনার নিজস্ব মতামত রাখুন।

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <RelativeLayout
        android:id="@+id/body_layout"
        android:layout_width="match_parent"
        android:layout_height="@dimen/glass_card_body_height"
        android:layout_marginLeft="@dimen/glass_card_margin"
        android:layout_marginTop="@dimen/glass_card_margin"
        android:layout_marginRight="@dimen/glass_card_margin"
        tools:ignore="UselessLeaf"
        >

        <!-- Put your widgets inside this RelativeLayout. -->

    </RelativeLayout>

    <LinearLayout
        android:id="@+id/footer_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|left"
        android:layout_marginLeft="@dimen/glass_card_margin"
        android:layout_marginBottom="@dimen/glass_card_footer_margin"
        android:layout_marginRight="@dimen/glass_card_margin"
        android:orientation="horizontal"
        >

        <!-- The footer view will grow to fit as much content as possible while the
             timestamp view keeps a fixed width. If the footer text is too long, it
             will be ellipsized with a 40px margin between it and the timestamp. -->

        <TextView
            android:id="@+id/footer"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ellipsize="end"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceSmall"
            />

        <TextView
            android:id="@+id/timestamp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/glass_card_margin"
            android:ellipsize="end"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceSmall"
            />

    </LinearLayout>

</FrameLayout>

বাম কলাম লেআউট

এটি একটি 240px বাম কলাম এবং 400px ডান কলামকে দুটি RelativeLayout আকারে সংজ্ঞায়িত করে যা আপনি আপনার মতামত রাখতে পারেন৷

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <RelativeLayout
        android:id="@+id/left_column"
        android:layout_width="@dimen/glass_card_left_column_width"
        android:layout_height="match_parent"
        >

        <!-- Put widgets for the left column inside this RelativeLayout. -->

    </RelativeLayout>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="@dimen/glass_card_body_height"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="@dimen/glass_card_two_column_margin"
        android:layout_marginRight="@dimen/glass_card_margin"
        android:layout_marginTop="@dimen/glass_card_margin"
        android:layout_toRightOf="@+id/left_column"
        tools:ignore="UselessLeaf"
        >

        <!-- Put widgets for the right column inside this RelativeLayout. -->

    </RelativeLayout>

    <LinearLayout
        android:id="@+id/footer_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_gravity="bottom|left"
        android:layout_marginBottom="@dimen/glass_card_footer_margin"
        android:layout_marginLeft="@dimen/glass_card_two_column_margin"
        android:layout_marginRight="@dimen/glass_card_margin"
        android:layout_toRightOf="@+id/left_column"
        android:orientation="horizontal"
        >

        <!--
             The footer view will grow to fit as much content as possible while the
             timestamp view keeps a fixed width. If the footer text is too long, it
             will be ellipsized with a 40px margin between it and the timestamp.
        -->

        <TextView
            android:id="@+id/footer"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ellipsize="end"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceSmall"
            />

        <TextView
            android:id="@+id/timestamp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/glass_card_margin"
            android:ellipsize="end"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceSmall"
            />

    </LinearLayout>

</RelativeLayout>

স্ট্যান্ডার্ড মাত্রা

স্ট্যান্ডার্ড গ্লাস শৈলী মেনে চলতে পূর্ববর্তী লেআউট বা আপনার নিজস্ব লেআউটের সাথে এই ফাইলটি ব্যবহার করুন। আপনার Android প্রকল্পে res/values/dimens.xml হিসাবে এই ফাইলটি তৈরি করুন।

<?xml version="1.0" encoding="utf-8"?>

<resources>

    <!-- The recommended margin for the top, left, and right edges of a card. -->
    <dimen name="glass_card_margin">40px</dimen>

    <!-- The recommended margin between the bottom of the card and the footer. This is
         an adjusted value so that the baseline of the text in the footer sits 40px
         from the bottom of the card, matching the other margins. -->
    <dimen name="glass_card_footer_margin">33px</dimen>

    <!-- The recommended margin for the left column of the two-column card. -->
    <dimen name="glass_card_two_column_margin">30px</dimen>

    <!-- The maximum height of the body content inside a card. -->
    <dimen name="glass_card_body_height">240px</dimen>

    <!-- The width of the left column in the two-column layout. -->
    <dimen name="glass_card_left_column_width">240px</dimen>

</resources>