0

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>
Jongware
  • 22,200
  • 8
  • 54
  • 100
MrStank
  • 314
  • 4
  • 10
  • As the answer below suggests, I'm wondering why you need fragments and can't just make a class to handle inflating the view and the view's logic – Will Molter Aug 23 '16 at 18:37
  • Agreed, definitely don't use Fragments here. Always ask "do I need a Fragment?" The only time the answer is yes is if you need to encapsulate logic which requires lifecycle callbacks. In 99% of cases a View/ViewGroup will be better and avoid headaches. Here all you need is `new TextView()` – Jahnold Aug 23 '16 at 18:41
  • you may use replace function of fragment instead of add – Umar Ata Aug 23 '16 at 19:01
  • Well I wanted to add a little phone/call icon next to the number you can easily call the number. So I need more than a TextView added to the number. But a ViewGroup. I never thought of that. I will look into ViewGroups as I have never used them. I am pretty new to Android Development lol. – MrStank Aug 23 '16 at 19:25
  • If you want to add an icon look at the drawableLeft/Right properties of TextView. – Ivan Wooll Aug 23 '16 at 20:08

2 Answers2

2

You are right, you are adding new fragments on top of old. trans.add inserts the fragment in to the specified view. trans.replace would insert the fragment replacing whatever was previously there but I'm guessing that's not what you're looking to do here. Reading between the lines it seems that you want to display a list of numbers? If that's the case you could always just add views to an existing layout as the other answer suggests. This question will set you in the right direction. Failing that a good old ListView will do the job just as nicely.

Community
  • 1
  • 1
Ivan Wooll
  • 4,145
  • 3
  • 23
  • 34
1

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);
    }
}
Jahnold
  • 7,623
  • 2
  • 37
  • 31
  • This was perfect for me! Thank you so much man. Although, I don't quite understand what is going on here. I am going to study the code, and do some research so I can use this solution again if I ever run into a problem like this. Which I'm sure I will lol. Again, thanks! – MrStank Aug 23 '16 at 20:23