0

I appreciate my question seems a duplicate of this however, I am tackling the same thing in a different manner, so I am unable to find a suitable solution.

I am working with fragments and in this particular scenario, I have two fragments, fragment A and fragment B.

Fragment A calls fragment B, in fragment B a call to an external DB is made and the data is saved in shared preferences.

This data is then passed back to fragment A, a loop is then made which will loop out the IDs stored in shared preferences and add them to a button, which is added to a Linear Layout.

This is all working fine, however now I would like to add an OnClickListeners to each button. Each button will have a different function (basically, each button will represent and access an individual question stored in my DB).

Here is my method where the dynamic button is created:

@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");
            }
        }


    }

}

Then I am trying to call each button here

@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>

At first, I thought to access each button I would need to use generateViewId() however, the ID is dependant on the position of the button within the XML.

So then I read that setTag is needed instead - however now I am getting confused on how to implement it and access it within the individual button within the onClick.

Any assistance would be really appreciated.

Display name
  • 730
  • 2
  • 8
  • 23
  • Well, your solution seems feasible but, I would a bit long: When u send data from Fragment B to A do it via your activity, which is professional of doing. Then, when u get list of button data inflate each of them via loop. Also, while looping, set OnclickListener to each button by id from the DB of that button. Then in another method which receives on click command do what you want with your button as id from db will get all your data neede by that id –  Sep 01 '17 at 11:04
  • @SA can you check my method below? – phpdroid Sep 01 '17 at 11:13

2 Answers2

0

I don't know how well my method will be appreciated but I use this method in my project.
So I Dynamically create id for my buttons as

    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;

here idz can be unique id(ex userID) from database,you can loop through everytime and cerate new ids and set them to respective button
what i do in my xml is call a function on click:-

<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"
        />

here am calling a click function
and in click function i can handle request for every button which is clicked like:-

 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
phpdroid
  • 1,642
  • 1
  • 18
  • 36
  • yep, this approach, but a bit not that i mentioned))) When u create id of buttonsm that ids could be brought db. because ids u create above could not be present in db, which may result in "no such id error". So it is better to get what we have in db and the rest seems fine )) –  Sep 01 '17 at 11:20
  • @SA here `idz` parameter is taken from database itself for creating relevant ids that will be present in db – phpdroid Sep 01 '17 at 11:23
  • what if you deleted one of your ids which is in between, so consequence changes from 1,2,3 .. 6 to 1,3 ... 6. So the consequence should not be considered as in your case u considered )) –  Sep 01 '17 at 11:41
  • am just passing the ids as it is from the database so if my id is `124522` so my first button will be `1245221` and second `1245222` so on...am just sending these from my db second id can be `2` doesn't matter – phpdroid Sep 01 '17 at 11:46
  • whatever, the point is ids should be conflicting or something else. If everything is working fine then, good job )) –  Sep 01 '17 at 11:48
  • in my case it is hope this method helps him – phpdroid Sep 01 '17 at 11:48
  • yeap. anyways, he can comment if something wents wrong, still u got the idea, thanx for that )) –  Sep 01 '17 at 11:49
  • @phpdroid thanks for the answer - I am sure your answer is something that would be useful - although if you could help me to add this in my existing code I have added, it would be appreciated as I am not familiar with the logic. Thanks! – Display name Sep 01 '17 at 11:58
  • @Displayname where you using `generateViewId()` method create your own ID as I have mentioned they are integers values only! – phpdroid Sep 01 '17 at 12:01
  • But I am not sure how many Buttons will be needed so I need to set the IDs dynamically, I don't think this will work? I guess it will need to be a loop instead. – Display name Sep 01 '17 at 12:10
  • these are the number of buttons per fragmet and populate number of times you need fragment – phpdroid Sep 01 '17 at 12:18
0

In the end I did further research on setTag and decided that this was the way to go.

I included btn_question.setTag(value); as part of my enhanced for loop, as this would create a unique tag regardless of where the element was on my XML.

I then added btn_question.setOnClickListener(this); again within the enhanced loop, and then called the relative button that I had clicked on as follows.

@Override
public void onClick(View view) {

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

    }

The toast confirms that the selected value is correct.

Display name
  • 730
  • 2
  • 8
  • 23