I am working on an Android app and using the TabLayout with two fragments, Map and Discovery. In the Discovery fragment, I have a ListView that I am using to display devices that the app has connected to. I am trying to add a feature that will cause the Map fragment to be loaded once an entry in the ListView is clicked. An attempt at implementing this feature was done by adding the code
Fragment fragment = new MapFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_map,fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
to the OnClickListener of the ListView where R.id.content_map is the id of the layout file used with the MapFragment class. I found the above code here. Below are the DiscoveryFragment and MapFragment class definitions.
public class DiscoveryFragment extends Fragment {
private DhcpInfo mDhcpInfo = null;
private ArrayList<String> mArrayList = null;
private final int TASK_COMPLETE = 1;
private Handler mHandler = null;
private final String IP_KEY = "IPs";
private DiscoveryArrayAdapter mArrayAdapter = null;
private final String ROBOT_ID = "create2";
private AppDatabase db = null;
private int mTaskCounterVar = 0;
public DiscoveryFragment() {
// This is an anonymous class which extends the Handler class
// Handler object is attached to the UI thread
mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message message) {
// Get the message string from the Message
super.handleMessage(message);
Bundle bundle = message.getData();
ArrayList<String> msgs = bundle.getStringArrayList(IP_KEY);
if(msgs != null) {
mArrayList.addAll(msgs);
}
mArrayAdapter.notifyDataSetChanged();
}
};
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WifiManager wifiManager = (WifiManager) getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
mDhcpInfo = wifiManager.getDhcpInfo();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ListView listView = null;
final View discoveryView = inflater.inflate(R.layout.fragment_discovery,container,false);
mArrayList = new ArrayList<String>();
new Thread(new FindRobotTask()).start();
db = Room.databaseBuilder(discoveryView.getContext(), AppDatabase.class, "AppDatabase").build();
// Setup a new thread to perform network operations
// Use the ArrayAdapter to register new content to the ListView
mArrayAdapter = new DiscoveryArrayAdapter(discoveryView.getContext(), mArrayList);
FloatingActionButton fab = (FloatingActionButton) discoveryView.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new FindRobotTask()).start();
mArrayAdapter.notifyDataSetChanged();
}
});
listView = (ListView)discoveryView.findViewById(R.id.listview);
listView.setAdapter(mArrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Fragment fragment = new MapFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_map,fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return discoveryView;
}
class FindRobotTask implements Runnable {
// Implement the run method
public void run() {
Bundle bundle = new Bundle();
Message message = mHandler.obtainMessage();
ArrayList<String> ipArrayList = new ArrayList<String>();
try {
String msg = "Hello";
String ip = "";
InetAddress group = InetAddress.getByName("224.3.29.71");
MulticastSocket sock = new MulticastSocket();
sock.joinGroup(group);
byte[] bytes = msg.getBytes();
DatagramPacket hi = new DatagramPacket(bytes, bytes.length, group, 10000);
sock.send(hi);
byte[] buf = new byte[1000];
String recvMsg = "";
InetAddress address = null;
for(int i = 0; i < 10 && !"iRobot Create 2".equals(recvMsg); i++) {
DatagramPacket recv = new DatagramPacket(buf, buf.length);
sock.receive(recv);
recvMsg = new String(recv.getData(), 0, recv.getLength());
address = recv.getAddress();
}
ip = address.getHostAddress();
List<Robot> robotsWithIp = db.robotDao().loadByIp(ip);
// If a corresponding table entry is not found,
// add the robot to the database.
if(mTaskCounterVar == 0) {
if(robotsWithIp.size() == 0) {
ipArrayList.add(recvMsg + ": " + ip);
Robot robot = new Robot(recvMsg, ip);
db.robotDao().insert(robot);
mTaskCounterVar++;
// Else load the robot from the database
} else if (robotsWithIp.size() > 0) {
for(Robot robot : robotsWithIp) {
if(robot != null) {
ipArrayList.add(robot.name + ": " + robot.ip);
}
}
mTaskCounterVar++;
}
}
sock.leaveGroup(group);
sock.close();
} catch(UnknownHostException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
bundle.putStringArrayList(IP_KEY,ipArrayList);
message.setData(bundle);
mHandler.sendMessage(message);
}
}
}
public class MapFragment extends Fragment {
public MapFragment() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_map, container, false);
}
}
However, when I run the app, the DiscoveryFragment does not get replaced with the MapFragment upon clicking an entry in the list view. Can anyone point me to where I might be going wrong? I believe it may be the id passed to the replace method, but I'm really not sure.