使用共享首选项动态创建按钮并设置 onClickListener 以访问按钮关联数据

Dynamically creating Buttons using Shared Preferences and setting onClickListener to access button associated data

我很感激我的问题似乎与 this 重复,但是,我正在以不同的方式处理同一件事,所以我找不到合适的解决方案。

我正在处理片段,在这个特定场景中,我有两个片段,片段 A片段 B.

片段A调用片段B,在片段B中调用外部数据库制作完成并将数据保存在共享首选项中。

然后将此数据传回片段A,然后进行循环,将循环出存储在shared preferences中的ID并将它们添加到按钮,添加到线性布局中。

一切正常,但是现在我想为每个按钮添加一个 OnClickListeners。每个按钮都有不同的功能(基本上,每个按钮将代表和访问存储在我的数据库中的单个问题)。

这是我创建动态按钮的方法:

@TargetApi(Build.VERSION_CODES.M)
public void createQuestionButton() {

    //get all the question_ids from shared pref, that have been stored from the SetQuestion Activity
    //in the allQuestionIDS() method
    String questionNumber = pref.getString(Constants.All_QUESTION_IDS, "");


    //converting the above String back into a List
    questionNumber = questionNumber.substring(1, questionNumber.length() - 1);
    //split the array using the comma
    String[] array = questionNumber.split(",");
    //Converting questionArray array to a list using Arrays.asList()
    List list = Arrays.asList(array);


    if (!questionNumber.equals("") && !questionNumber.equals(null)) {

        for (final Object value : list) {

            try {

        /*Dynamically create new Button which includes the question number
          */

                btn_question = new AppCompatButton(getActivity());

        /*LayoutParams (int width, int height,float weight)
        As LayoutParams is defaulted in px, I have called a method called dpToPX to make sure
        the dynamically added Button is the same size on all devices.
         */
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dpToPx(280), dpToPx(45), 1);
                btn_question.setBackgroundColor(Color.parseColor("#3B5998"));
                btn_question.setTextColor(Color.WHITE);
                btn_question.setText("Question " + value);
                btn_question.setGravity(Gravity.CENTER);
                //generate unique ID for each new Button dynamically created
                btn_question.setId(View.generateViewId());
                params.setMargins(0, dpToPx(10), 0, dpToPx(10));
                btn_question.setPadding(0, 0, 0, 0);
                btn_question.setLayoutParams(params);
                //allEds.add(btn_question);
                btn_question.setTag(btn_question);

                btn_question.setOnClickListener(this);
                mLayout.addView(btn_question);



                //Toast.makeText(getActivity(), "Question ID = " + btn_question.getId(),
                       // Toast.LENGTH_LONG).show();

            } catch (Exception e) {
                Log.d(TAG, "Failed to create new button");
            }
        }


    }

}

然后我尝试在这里调用每个按钮

@Override
public void onClick(View view) {


    switch (view.getId())
    {

        case R.id.btn_add_question:
            goToQuestion();

            break;

        case R.id.btn_remove_all_questions:
            //show dialog box asking if user definitely wants to remove all questions
            showDialog();
            break;


      //  case btn_question.getId():
    }

}

XML

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

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/create_questions"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/facebookBlue"
      android:orientation="vertical"
      android:weightSum="1">


    <android.support.design.widget.TextInputEditText
        android:id="@+id/tv_setQuestions"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:inputType="none"
        android:text="@string/setQuestions"
        android:textColor="@android:color/background_light"
        android:textColorLink="@android:color/background_light"
        android:textSize="30sp"
        android:textStyle="bold" />


    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="1">

        <TextView
            android:id="@+id/textView3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:text="Press 'Add Question' to Add a Question and it's Answer"
            android:textColor="@android:color/background_light"
            android:textSize="24sp" />

    </FrameLayout>


    <LinearLayout
        android:id="@+id/buttonGroupLayout"   <-----Here is where the dynamic button is added
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="vertical">

    </LinearLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="1">

        <android.support.v7.widget.AppCompatButton
            android:id="@+id/btn_add_question"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="40dp"
            android:layout_marginTop="8dp"
            android:background="@color/colorPrimary"
            android:text="Add Question"
            android:textColor="@android:color/white" />

    </FrameLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="1">

        <android.support.v7.widget.AppCompatButton
            android:id="@+id/btn_remove_all_questions"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="40dp"
            android:background="@color/colorPrimary"
            android:text="@string/removeAllQuestions"
            android:textColor="@android:color/white" />

    </FrameLayout>


    <ProgressBar
        android:id="@+id/progress"
        style="@style/Base.Widget.AppCompat.ProgressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/btn_submit_team"
        android:layout_marginTop="26dp"
        android:indeterminate="true"
        android:visibility="invisible" />


</LinearLayout>

起初,我想访问我需要使用 generateViewId() 的每个按钮,但是,ID 取决于按钮在 XML 中的位置。

然后我读到需要 setTag - 但是现在我对如何实现它以及如何在 onClick 的单个按钮中访问它感到困惑。

如有任何帮助,我们将不胜感激。

我不知道我的方法会有多受欢迎,但我在我的项目中使用了这种方法。
所以我为我的按钮动态创建 id

    int buttona=10*idz+1;
    int buttonab=10*idz+2;
    int buttonac=10*idz+3;
    int buttonad=10*idz+4;
    int buttonae=10*idz+5;
    int buttonaf=10*idz+6;

此处idz可以是数据库中的唯一ID(例如用户ID),您可以每次循环并创建新ID并将它们设置为相应的按钮
我在 xml 中所做的是在点击时调用一个函数:-

<ImageButton android:background="@drawable/share"
        android:layout_height="36dp"
        android:layout_width="36dp"
        android:padding="10dp"
        android:onClick="click"
        android:layout_marginTop="10dp"
        android:id="@+id/button_share"
        />

这里调用了一个click函数
click 函数中,我可以处理每个被点击的按钮的请求,例如:-

 public void click(View view) {

    Context context = getApplicationContext();
    final int position = view.getId();
    int button_number = position % 10;
    int id = position / 10;
    // now I can know which button is click through button_number can do respectively through if loop
    // what i have to do to data using id

最后我对 setTag 做了进一步的研究,并决定这是要走的路。

我将 btn_question.setTag(value); 作为我增强的 for 循环的一部分,因为无论元素在我的 XML.

上的什么位置,这都会创建一个唯一的标签

然后我在增强循环中再次添加btn_question.setOnClickListener(this);,然后调用我点击的相关按钮如下。

@Override
public void onClick(View view) {

    view.getTag();{
        Toast.makeText(getActivity(), "Question ID = " + view.getTag(),
                 Toast.LENGTH_LONG).show();

    }

吐司确认选择的值是正确的。