So I am developing an app that uses firebase to load a list of buses, and if they have arrived or not. I'm relatively new to this and am trying to use fragments. I can get the fragment to load in successfully with the list of buses, but when I scroll through them it leaves behind a copy of the items, as seen here:
MainActivity:
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle(null);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
BusFragment busFragment = new BusFragment();
transaction.add(R.id.buscontainer, busFragment);
transaction.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
MainActivity xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.jackheinemann.schoolbus.MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/my_toolbar"
android:minHeight="?attr/actionBarSize"
android:background="@color/colorPrimary"
android:layout_width="match_parent"
android:layout_height="64dp"/>
<FrameLayout
android:id="@+id/buscontainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
</FrameLayout>
</LinearLayout>
BusFragment:
public class BusFragment extends Fragment {
public boolean isInitialized = false;
// Database Instance Variables
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mBusref;
private ChildEventListener mChildEventListener;
// Tablerow ID's
final Integer[] tableRows = {R.id.tablerow1, R.id.tablerow2, R.id.tablerow3,
R.id.tablerow4, R.id.tablerow5, R.id.tablerow6, R.id.tablerow7, R.id.tablerow8,
R.id.tablerow9, R.id.tablerow10, R.id.tablerow11, R.id.tablerow12,
R.id.tablerow13, R.id.tablerow14, R.id.tablerow15};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View busView = inflater.inflate(R.layout.activity_bus_fragment, container, false);
onSignedInInitialize();
init();
return busView;
}
public void onSignedInInitialize() {
if (mChildEventListener == null) {
mFirebaseDatabase = FirebaseDatabase.getInstance();
mBusref = mFirebaseDatabase.getReference().child("buses");
mChildEventListener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
String bus_name = dataSnapshot.getKey();
Boolean bus_loc = dataSnapshot.getValue(Boolean.class);
String bus_location = Boolean.toString(bus_loc);
Integer findview = grabBusNumber(bus_name);
TextView textView = (TextView) getView().findViewById(findview);
textView.setText(bus_location);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};
mBusref.addChildEventListener(mChildEventListener);
}
}
public void init() {
mBusref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
int i = 1;
View view = getView();
for (DataSnapshot buslist : dataSnapshot.getChildren()) {
if (i < 16) {
String bus = "Bus " + Integer.toString(i);
Boolean location = buslist.getValue(Boolean.class);
TextView bus_name = new TextView(getActivity());
TextView bus_location = new TextView(getActivity());
TableRow.LayoutParams params = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 1f);
bus_name.setText(bus);
bus_name.setTextSize(30);
bus_name.setLayoutParams(params);
bus_name.setGravity(Gravity.CENTER);
bus_location.setText(Boolean.toString(location));
bus_location.setTextSize(30);
bus_location.setLayoutParams(params);
bus_location.setGravity(Gravity.CENTER);
Integer identifier = i;
bus_location.setId(identifier);
if (view != null) {
TableRow tableRow = (TableRow) view.findViewById(tableRows[i - 1]);
tableRow.addView(bus_name);
tableRow.addView(bus_location);
i++;
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
isInitialized = true;
}
private Integer grabBusNumber(String bus_id) {
String string;
if (bus_id.charAt(1) != '_') {
string = Character.toString(bus_id.charAt(0)) + Character.toString(bus_id.charAt(1));
} else {
string = Character.toString(bus_id.charAt(0));
}
Integer integer = Integer.parseInt(string);
return integer;
}
}
activity_bus_fragment.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_bus_fragment"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.jackheinemann.schoolbus.BusFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:id="@+id/tablerow1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow3"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow4"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow5"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow6"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow7"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow8"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow9"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow10"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow11"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow12"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow13"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow14"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:id="@+id/tablerow15"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</TableLayout>
</ScrollView>
</LinearLayout>
For anyone here looking for an answer, the way I fixed the issue was changing the fragment additions to fragment replacements. For some reason it was adding the fragments twice, hence the "shadows". Replacing instead of adding ensured there was only one loaded and fixed the issue.