একটি বিন্যাস স্ফীত করে একটি কাস্টম ভিউ তৈরি করবেন?


107

আমি একটি কাস্টম ভিউ তৈরির চেষ্টা করছি যা আমি একাধিক স্থানে ব্যবহার করে এমন একটি নির্দিষ্ট বিন্যাস প্রতিস্থাপন করবে, তবে আমি তা করতে সংগ্রাম করছি।

মূলত, আমি এটি প্রতিস্থাপন করতে চাই:

<RelativeLayout
 android:id="@+id/dolphinLine"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
    android:layout_centerInParent="true"
 android:background="@drawable/background_box_light_blue"
 android:padding="10dip"
 android:layout_margin="10dip">
  <TextView
   android:id="@+id/dolphinTitle"
   android:layout_width="200dip"
   android:layout_height="100dip"
   android:layout_alignParentLeft="true"
   android:layout_marginLeft="10dip"
   android:text="@string/my_title"
   android:textSize="30dip"
   android:textStyle="bold"
   android:textColor="#2E4C71"
   android:gravity="center"/>
  <Button
   android:id="@+id/dolphinMinusButton"
   android:layout_width="100dip"
   android:layout_height="100dip"
   android:layout_toRightOf="@+id/dolphinTitle"
   android:layout_marginLeft="30dip"
   android:text="@string/minus_button"
   android:textSize="70dip"
   android:textStyle="bold"
   android:gravity="center"
   android:layout_marginTop="1dip"
   android:background="@drawable/button_blue_square_selector"
   android:textColor="#FFFFFF"
   android:onClick="onClick"/>
  <TextView
   android:id="@+id/dolphinValue"
   android:layout_width="100dip"
   android:layout_height="100dip"
   android:layout_marginLeft="15dip"
   android:background="@android:drawable/editbox_background"
   android:layout_toRightOf="@+id/dolphinMinusButton"
   android:text="0"
   android:textColor="#2E4C71"
   android:textSize="50dip"
   android:gravity="center"
   android:textStyle="bold"
   android:inputType="none"/>
  <Button
   android:id="@+id/dolphinPlusButton"
   android:layout_width="100dip"
   android:layout_height="100dip"
   android:layout_toRightOf="@+id/dolphinValue"
   android:layout_marginLeft="15dip"
   android:text="@string/plus_button"
   android:textSize="70dip"
   android:textStyle="bold"
   android:gravity="center"
   android:layout_marginTop="1dip"
   android:background="@drawable/button_blue_square_selector"
   android:textColor="#FFFFFF"
   android:onClick="onClick"/>
</RelativeLayout>

এটা দ্বারা:

<view class="com.example.MyQuantityBox"
    android:id="@+id/dolphinBox"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:myCustomAttribute="@string/my_title"/>

সুতরাং, আমি একটি কাস্টম বিন্যাস চাই না, আমি একটি কাস্টম ভিউ চাই (এই ভিউটির পক্ষে শিশু হওয়া সম্ভব হবে না)।

মাইকিউন্টিটিবক্সের এক উদাহরণ থেকে অন্য ক্ষেত্রে পরিবর্তিত হতে পারে এমন একমাত্র শিরোনাম। আমি খুব XML এ এটি নির্দিষ্ট করতে সক্ষম হতে চাই (যেমন আমি শেষ XML লাইনে করি)

কিভাবে আমি এটি করতে পারব? আমি কি রিলেটিভলআউটটি একটি এক্সএমএল ফাইলটিতে / রেস / লেআউটে রেখে আমার মাইবক্সকুনটিটি ক্লাসে স্ফীত করব? যদি হ্যাঁ আমি কীভাবে করব?

ধন্যবাদ!


: "চক্রবৃদ্ধি নিয়ন্ত্রণ" Android এর মধ্যে, এবং এই লিঙ্কটি দেখুন stackoverflow.com/questions/1476371/...
greg7gkb

উত্তর:


27

হ্যাঁ, আপনি এটা করতে পারেন. রিলেটিভলআউট, লিনিয়ারলআউট ইত্যাদির মতামত তাই কাস্টম বিন্যাসটি একটি কাস্টম ভিউ। বিবেচনা করার মতো কিছু কারণ আপনি যদি পছন্দসই লেআউট তৈরি করতে চান তবে পারেন।

আপনি যা করতে চান তা একটি যৌগিক নিয়ন্ত্রণ তৈরি করুন। আপনি রিলেটিভলআউটের একটি সাবক্লাস তৈরি করবেন, কোডে আপনার সমস্ত উপাদান যুক্ত করুন (টেক্সটভিউ, ইত্যাদি), এবং আপনার কনস্ট্রাক্টরে আপনি এক্সএমএল থেকে পাস করা বৈশিষ্ট্যগুলি পড়তে পারেন। তারপরে আপনি সেই শিরোনামটি আপনার শিরোনাম টেক্সটভিউতে পাস করতে পারেন।

http://developer.android.com/guide/topics/ui/custom-components.html


130

কিছুটা পুরানো, তবে আমি ভেবেছিলাম কীভাবে আমি এটি করব, চুবসন্ডবসের উত্তরের উপর ভিত্তি করে: আমি ব্যবহার করি FrameLayout( ডকুমেন্টেশন দেখুন ), যেহেতু এটি একটি একক দর্শন ধারণ করার জন্য ব্যবহৃত হয়, এবং এটি এক্সএমএল থেকে ভিউতে উত্সাহিত করে।

কোড অনুসরণ:

public class MyView extends FrameLayout {
    public MyView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initView();
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public MyView(Context context) {
        super(context);
        initView();
    }

    private void initView() {
        inflate(getContext(), R.layout.my_view_layout, this);
    }
}

13
যেহেতু ভিউ ক্লাসে স্ট্যাটিক ইনফ্লেট () পদ্ধতি রয়েছে লেআউটআইনফ্লেটার.ফ্রোম ()
বাহ্যিক

1
এটি কি এখানে থেকে কেবল জোহানসের সমাধান নয়: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 17836695/… তবুও, এটি এর মধ্যে অন্য লেআউটকে স্ফীত করে। সুতরাং এটি আমার পক্ষে অনুমান করা সবচেয়ে ভাল সমাধান নয়।
টোবিয়াস রিখ

3
এটি তবে জোহানেস সমাধানটি 7.24.13 থেকে, এবং মনটি 7.1.13 থেকে ছিল ... এছাড়াও, আমার সমাধান ফ্রেমলাউট ব্যবহার করে যা কেবলমাত্র একটি ভিউ (সমাধানে উল্লেখ করা ডক্টে লিখিত আছে) ধারণ করে। সুতরাং প্রকৃতপক্ষে এটি কোনও ভিউয়ের জন্য স্থানধারক হিসাবে ব্যবহৃত হবে। আমি এমন কোনও সমাধান জানি না যা স্ফীত ভিউয়ের জন্য কোনও স্থানধারক ব্যবহার করে চালিত হয় না।
ফক্স

আমি পাই না। এই পদ্ধতিটি (স্ফীতি) একটি দৃশ্য প্রদান করে, যা উপেক্ষা করা হয়। দেখে মনে হচ্ছে আপনার এটি বর্তমান দর্শনে যুক্ত করা দরকার।
জেফ্রি ব্লাটম্যান

1
@ জেফ্রি ব্লাটম্যান দয়া করে ভিউ.ইনফ্লেট পদ্ধতিটি পরীক্ষা করে দেখুন , আমরা এইটি ব্যবহার করি ( thisতৃতীয় প্যারামিটার হিসাবে মূলটি নির্দিষ্ট করে )
ভি 1raNi

36

এক্সএমএল থেকে স্ফীত করে কাস্টমভিউ (কম্পাউন্ডভিউ) তৈরি করার জন্য এখানে একটি সাধারণ ডেমো

attrs.xml

<resources>

    <declare-styleable name="CustomView">
        <attr format="string" name="text"/>
        <attr format="reference" name="image"/>
    </declare-styleable>
</resources>

CustomView.kt

class CustomView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
        ConstraintLayout(context, attrs, defStyleAttr) {

    init {
        init(attrs)
    }

    private fun init(attrs: AttributeSet?) {
        View.inflate(context, R.layout.custom_layout, this)

        val ta = context.obtainStyledAttributes(attrs, R.styleable.CustomView)
        try {
            val text = ta.getString(R.styleable.CustomView_text)
            val drawableId = ta.getResourceId(R.styleable.CustomView_image, 0)
            if (drawableId != 0) {
                val drawable = AppCompatResources.getDrawable(context, drawableId)
                image_thumb.setImageDrawable(drawable)
            }
            text_title.text = text
        } finally {
            ta.recycle()
        }
    }
}

custom_layout.xml

আমরা উচিত ব্যবহার mergeএখানে পরিবর্তে ConstraintLayoutকারণ

আমরা যদি ConstraintLayoutএখানে ব্যবহার করি তবে বিন্যাস স্তরক্রমটি হবে ConstraintLayout-> ConstraintLayout-> ImageView+ TextView=> আমাদের 1 টি রিডানডান্ট>> ConstraintLayoutপারফরম্যান্সের জন্য খুব ভাল নয়

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:parentTag="android.support.constraint.ConstraintLayout">

    <ImageView
        android:id="@+id/image_thumb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:ignore="ContentDescription"
        tools:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/text_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="@id/image_thumb"
        app:layout_constraintStart_toStartOf="@id/image_thumb"
        app:layout_constraintTop_toBottomOf="@id/image_thumb"
        tools:text="Text" />

</merge>

ক্রিয়াকলাপ_মন.এক্সএমএল ব্যবহার করা

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <your_package.CustomView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#f00"
        app:image="@drawable/ic_android"
        app:text="Android" />

    <your_package.CustomView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#0f0"
        app:image="@drawable/ic_adb"
        app:text="ADB" />

</LinearLayout>

ফলাফল

এখানে চিত্র বর্ণনা লিখুন

গিথুব ডেমো


4
এটি হয় এই থ্রেডে গৃহীত বা সর্বাধিক ভোট দেওয়া উত্তর হওয়া উচিত কারণ এটি অপ্রয়োজনীয় বিন্যাস স্তরক্রমের উল্লেখ করে।
ফরিদ

15

আমি নীচে প্রদর্শিত হিসাবে লেআউটআইনফ্লেটার ব্যবহার করুন।

    public View myView() {
        View v; // Creating an instance for View Object
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.myview, null);

        TextView text1 = v.findViewById(R.id.dolphinTitle);
        Button btn1 = v.findViewById(R.id.dolphinMinusButton);
        TextView text2 = v.findViewById(R.id.dolphinValue);
        Button btn2 = v.findViewById(R.id.dolphinPlusButton);

        return v;
    }

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

7

অনুশীলনে, আমি খুঁজে পেয়েছি যে আপনাকে কিছুটা সতর্ক হওয়া দরকার, বিশেষত যদি আপনি বারবার কিছুটা এক্সএমএল ব্যবহার করছেন। ধরুন, উদাহরণস্বরূপ, আপনার একটি টেবিল রয়েছে যা আপনি তালিকার প্রতিটি প্রবেশের জন্য একটি টেবিল সারি তৈরি করতে চান। আপনি কিছু এক্সএমএল সেট আপ করেছেন:

ইন my_table_row.xml:

<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android" 
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent" android:id="@+id/myTableRow">
    <ImageButton android:src="@android:drawable/ic_menu_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/rowButton"/>
    <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="TextView" android:id="@+id/rowText"></TextView>
</TableRow>

তারপরে আপনি এটিকে কয়েকটি কোড সহ সারিতে একবার তৈরি করতে চান। এটি ধরে নেওয়া হয় যে সারিগুলি সংযুক্ত করার জন্য আপনি প্যারেন্ট টেবিলআউট মাই টেবিলটি সংজ্ঞায়িত করেছেন।

for (int i=0; i<numRows; i++) {
    /*
     * 1. Make the row and attach it to myTable. For some reason this doesn't seem
     * to return the TableRow as you might expect from the xml, so you need to
     * receive the View it returns and then find the TableRow and other items, as
     * per step 2.
     */
    LayoutInflater inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v =  inflater.inflate(R.layout.my_table_row, myTable, true);

    // 2. Get all the things that we need to refer to to alter in any way.
    TableRow    tr        = (TableRow)    v.findViewById(R.id.profileTableRow);
    ImageButton rowButton = (ImageButton) v.findViewById(R.id.rowButton);
    TextView    rowText   = (TextView)    v.findViewById(R.id.rowText);

    // 3. Configure them out as you need to
    rowText.setText("Text for this row");
    rowButton.setId(i); // So that when it is clicked we know which one has been clicked!
    rowButton.setOnClickListener(this); // See note below ...           

    /*
     * To ensure that when finding views by id on the next time round this
     * loop (or later) gie lots of spurious, unique, ids.
     */
    rowText.setId(1000+i);
    tr.setId(3000+i);
}

রোবাটন.সেটঅনক্লিকলিস্টারিয়ার (এটি) পরিচালনা করার ক্ষেত্রে একটি সুস্পষ্ট সহজ উদাহরণের জন্য , প্রোগ্রামক্রমে তৈরির বোতামের জন্য অনক্লিক্লিশনারের দেখুন ।


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

আমার প্রশ্নটি দেখুন। stackoverflow.com/questions/48719970/…
হরিকৃষ্ণন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.