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.

2
  • 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 Commented Sep 1, 2017 at 11:04
  • @SA can you check my method below? Commented Sep 1, 2017 at 11:13

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

11 Comments

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 ))
@SA here idz parameter is taken from database itself for creating relevant ids that will be present in db
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 ))
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
whatever, the point is ids should be conflicting or something else. If everything is working fine then, good job ))
|
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.