Kyle Stankovich Kyle Stankovich - 3 months ago 12
Java Question

SOLVED - Fragments getting added on top of each other?

This may be a duplicate, but quite frankly, none of the other questions are helping me.

So I have a problem. I am making a Contacts Android application. When I press a contact to view it's number, only one number shows. Usually this is fine, because most people don't have multiple numbers for one contact. But when you do, you want to see all of the numbers. And this is my problem. I want to have multiple numbers displayed, but it does not work.

Only one number shows, but from debugging, I know for a fact that the actual number variables are there, they just are not being displayed correctly. So this has led me to believe that the two fragments are getting added on top of each other. And yes, the layout that they are being added to is a LinearLayout.

So, why the heck are my fragments being added on top of each other? I am using the Support Fragments and Support Fragment Manager btw. I have been trying to figure this out for a couple days. I honestly hate to just straight up ask, but I have no idea what I'm doing wrong this time. So if anyone could help me out here, that would be sweet.

Here is the code:

ContactActivity.java

//Create an intent
Intent intent = getIntent();
Bundle extras = intent.getExtras();

//Get extras
String contact_title = extras.getString("contact_title");
String[] contact_numbers = extras.getStringArray("contact_numbers");

...
...

//Add numbers
if(contact_numbers != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction trans = fragmentManager.beginTransaction();

//Add fragments
for(int i = 0; i < contact_numbers.length; i++) {
trans.add(R.id.contact_numbers, ContactNumberFragment.newInstance("contact_number", contact_numbers[i]), "ID: " + Integer.toString(i));
}

trans.commit();
}


ContactNumberFragment.java

//Adds an extra
public static ContactNumberFragment newInstance(String name, String text) {
ContactNumberFragment fragment = new ContactNumberFragment();

//Add extras
Bundle bundle = new Bundle();
bundle.putString(name, text);
fragment.setArguments(bundle);

return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_contact_number, container, false);
Bundle extras = getArguments();

String number = extras.getString("contact_number");
Log.i("NUMBER", number);

contactNumber_textView = (TextView)v.findViewById(R.id.contactNumber_textView);

//Set number text
if(contactNumber_textView != null) {
contactNumber_textView.setText(number);

Log.i("TEXT VIEW TEXT", contactNumber_textView.getText().toString());
}

return v;
}


activity_contact.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<include
layout="@layout/toolbar"
android:id="@+id/toolbar" />

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/contact_numbers"
android:layout_below="@id/toolbar">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/contactNumberTitle_title"
android:textColor="@color/textDarkLight"
android:textSize="@dimen/contactNumberTitle_textSize"
android:paddingStart="@dimen/mediumPadding"
android:paddingLeft="@dimen/mediumPadding"
android:paddingRight="@dimen/mediumPadding"
android:paddingTop="@dimen/smallPadding"
android:paddingBottom="@dimen/smallPadding" />
</LinearLayout>
</RelativeLayout>


fragment_contact_number.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ContactNumberFragment">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/contactNumber_textView"
android:text=""
android:textColor="@color/textDark"
android:textSize="@dimen/contactNumber_textSize"
android:padding="@dimen/smallPadding" />
</LinearLayout>


EDIT:
So the answer was very easy. Instead of using Fragments, I had to use something called ViewGroups. The fix was quite simple, thanks to @Jahnold. If you want to see the code, see his answer below. :)

Answer

Instead of using a Fragment here I would suggest just using a custom ViewGroup. For the example I have used a LinearLayout:

public class PhoneView extends LinearLayout {

    private TextView numberView;
    private ImageView phoneIcon;

    public PhoneView(Context context) {this(context, null);}
    public PhoneView(Context context, AttributeSet attrs) {this(context, attrs, 0);}
    public PhoneView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {

        setOrientation(HORIZONTAL);

        LayoutInflater inflater = LayoutInflater.from(getContext());
        View view = inflater.inflate(R.layout.view_phone, this, true);

        numberView = (TextView) view.findViewById(R.id.contact_number);
        phoneIcon = (ImageView) view.findViewById(R.id.phone_icon);

        phoneIcon.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                callNumber();
            }
        });
    }

    public void setContactNumber(String number) {
        numberView.setText(number);
    }

    private void callNumber() {
        //...
    }
}

Make the matching layout file view_phone.xml:

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

    <TextView
        android:id="@+id/contact_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <ImageView
        android:id="@+id/phone_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/icon_phone"
        />

</merge>

Then in your Activity you just need to do something like:

public void addNumbers(List<String> contactNumbers) {

    LinearLayout numberLayout = (LinearLayout) findViewById(R.id.contact_numbers);

    for (String number : contactNumbers) {

        PhoneView phoneView = new PhoneView(this);
        phoneView.setContactNumber(number);
        numberLayout.addView(phoneView);
    }
}