سؤال

لدي مشكلة في التعامل مع أزرار تم إنشاؤها ديناميكيًا على Android. أقوم بإنشاء أزرار N ويجب أن أفعل نفس الطريقة عند النقر فوق الزر ولكن يجب أن أعرف الزر الذي يتم النقر عليه.

for (int i = 0; i < NO_BUTTONS; i++){
        Button btn = new Button(this);
        btn.setId(2000+i);

        ...

        btn.setOnClickListener((OnClickListener) this);
        buttonList.addView(btn);
        list.add(btn);

أقوم بإضافة معرف معرف في كل زر ، وأنا أستخدم الطريقة أدناه لمعرفة الزر الذي تم النقر عليه. (خط btn.setId(2000+i); و btn.setOnClickListener((OnClickListener) this);). يتم تنفيذ هذه الطريقة أيضًا في النشاط.

@Override
public void onClick(View v) {
    switch (v.getId()){
        case 2000: selectButton(0);
        break;

        ...

        case 2007: selectButton(7);
        break;
    }
 }

هذا لا يبدو جيدًا بالنسبة لي ، لذا فأنا أسأل هل هناك طريقة أفضل للقيام بذلك؟ أو كيفية إرسال بعض المعلومات إلى حدث OnClick؟ أي اقتراحات؟

هل كانت مفيدة؟

المحلول

يمكنك إنشاء طريقة تقوم بإرجاع onClickListener وتأخذ زر كمعلمة. ثم استخدم هذه الطريقة لتعيين onClickListener في الحلقة الأولى التي لديك ..

تحديث: يمكن أن يكون الرمز يتأرجح على هذا المنوال:

View.OnClickListener getOnClickDoSomething(final Button button)  {
    return new View.OnClickListener() {
        public void onClick(View v) {
            button.setText("text now set.. ");    
        }
    };
}

كطريقة في النشاط ثم استخدامه في الحلقة مثل هذا

button.setOnClickListener(getOnClickDoSomething(button));

نصائح أخرى

حصلت على حل واحد لهذا .. استخدم هذا الرمز في onCreate

linear = (LinearLayout) findViewById(R.id.linear);

LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1.0f);

Button[] btn = new Button[num_array_name.length];
for (int i = 0; i < num_array_name.length; i++) {
    btn[i] = new Button(getApplicationContext());
    btn[i].setText(num_array_name[i].toString());
    btn[i].setTextColor(Color.parseColor("#000000"));
    btn[i].setTextSize(20);
    btn[i].setHeight(100);
    btn[i].setLayoutParams(param);
    btn[i].setPadding(15, 5, 15, 5);
    linear.addView(btn[i]);

    btn[i].setOnClickListener(handleOnClick(btn[i]));

}

بعد onCreate ، قم بإنشاء طريقة واحدة لعرض نوع الإرجاع. onClickListener مثل هذا ..

View.OnClickListener handleOnClick(final Button button) {
    return new View.OnClickListener() {
        public void onClick(View v) {
        }
    };
}
Button.OnClickListener btnclick = new Button.OnClickListener(){

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

        Button button = (Button)v;
    Toast.makeText(getApplicationContext(), button.getText().toString(),2).show();  
    }

};

اتصل بهذا المستمع بواسطة btn.setOnClickListener(btnclick);

لا ينبغي استخدام معرفات العرض لهذه الأغراض حيث يتم إنشاء معرفات العرض في وقت التجميع اعتمادًا على المعرفات المحددة في ملفات تخطيط XML.

ما عليك سوى وضع معرفاتك الخاصة في طريقة SESTAG () المتوفرة على مستوى العرض (لذلك ترثها الأزرار). يمكن أن تكون هذه "العلامة" أي شيء يسمح لك بالتعرف على وجهة نظر من الآخرين. يمكنك استرداد قيمتها مع getTag ().

بدلاً من ذلك ، استخدم وظيفة Settag () لتمييز بسهولة.

 for(int i=0;i<4;i++) {
     Button btn = new Button(this);
     btn.setTag(i);
     btn.setOnClickListener(new View.OnclickListener() {
         @Override
         public void onClick(View v) {
             int i=v.getTag();
             switch(i) {
                 case 1: btn.setText(i);
                     break;

                 case 2: btn.setText(i);
                     break;

                 case 3: btn.setText(i);
                     break;

                 case 4: btn.setText(i);
                     break;

                 default: btn.setText("Others");
             }
         }
     }

"هذا لا يبدو جيدًا بالنسبة لي" لماذا لا؟ ألا يعمل؟ يمكنك أيضًا إنشاء متغير عضو ثابت يحمل قائمة بجميع الأزرار المضافة ، ثم ابحث عن الزر الذي تم النقر عليه في تلك القائمة بدلاً من ذلك.

لا أعرف لماذا ترغب في إنشاء أزرار n ، يبدو أن قيمتك لـ n أكبر من 10 على الأقل ، إذا كنت لا تحاول إظهارها جميعًا مرة واحدة (أقصد كل منهم في شاشة واحدة ، لا تمرير) يمكنك محاولة إعادة تدوير الأزرار غير المرئية تمامًا كما نفعل لعرض القائمة باستخدام حامل عرض القائمة. هذا من شأنه أن يقلل من بصمة الذاكرة وأداء التعزيز ، ويميز الأزرار بناءً على النص الذي تحدده عليها أو علامة أو حتى يمكنك الاحتفاظ بمرجع إلى عدد صغير من الأزرار.

من الأفضل عدم العبث بالمعرفات ، تم تصميم أساليب Settag و GetTag لهذا الغرض ، إنها الطريقة السريعة والنظيفة لتعيين مجموعة من مستمعي الأزرار على تخطيط ديناميكي

قد تساعد هذه الإجابة:https://stackoverflow.com/a/5291891/2804001

public class MainActivity extends Activity implements View.OnClickListener
{

LinearLayout linearLayout;
Button [] button;
View.OnClickListener listener;
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    linearLayout=(LinearLayout)findViewById(R.id.parent_lay);
    String[] array={"U123","U124","U125"};
    int length=array.length;
    System.out.println("11111111111111111111111111");
    button=new Button[length];
    for(int i=0;i<length;i++)
    {
        button[i]=new Button(getApplicationContext());
        button[i].setId(i);
        button[i].setText("User" + i);
        button[i].setOnClickListener(this);
        linearLayout.addView(button[i]);
    }
}
@Override
public void onClick(View view)
{
    view.getId();
    Button button=(Button)findViewById(view.getId());
    button.setText("Changed");
}
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top