简体   繁体   中英

Android ViewPager Fragments With TabLayout Acting unexpectedly

My first major App is wreaking havoc once again. I have a tabLayout on my main activity used to easily switch between 3 fragments. Here are the labels for them

-"IP Info"

-"NET Scan"

-"Utilities"...

Ever since I started this activity 3 months ago, I have had odd behavior with my fragments. The largest issue is that nothing from my fragment appears when the activity is first launched. it is a blank page. I have to switch to another activity and then back to main activity either once or multiple times in order to get my content to display. To me the instances of blank fragments seem irregular, and I can't trace a solid error being thrown for it.

here is my Entire Main activity on the off chance that something is crewing with it:

public class MainActivity extends AppCompatActivity
    implements devicesFragment.OnListFragmentInteractionListener,
                IPInfoFragment.OnFragmentInteractionListener,
                ToolsSelectionFragment.OnFragmentInteractionListener
{
public SectionsPagerAdapter mSectionsPagerAdapter;
public ViewPager mViewPager;

private SharedPreferences myprefs;
private SharedPreferences.Editor editor;
private final String PREFS_NAME = "userPrefs";

private MyDevice mydev;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    mydev = new MyDevice(this);
    new MyDeviceWorker().execute();
    myprefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    editor = myprefs.edit();

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    // Create the adapter that will return a fragment fors each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);
}


public void setActionBarTitle(String title){
    getSupportActionBar().setTitle(title);
}

//region ACTIONBAR
@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_main2, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        //clear shared-preferences
        editor.clear();
        Intent logoutIntent = new Intent(MainActivity.this, LoginActivity.class);
        finish();
        startActivity(logoutIntent);
    }

    if (id == R.id.action_profile) {
        Intent intent = new Intent(this, ProfileActivity.class);
        startActivity(intent);
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void onListFragmentInteraction(Devices device) {
}
//endregion

//region ASYNCTASK_RUNNERS
private class MyDeviceWorker extends AsyncTask {

    @Override
    protected Object doInBackground(Object[] params) {

        mydev.setListNetworkInterfaces();
        mydev.setInterfacesByDisplayName();
        mydev.getSSIDName();
        mydev.getLocalAddresses("wlan0");

        return this;
    }
}
//endregion
@Override
public void onFragmentInteraction(String title) {

}

@Override
public void onFragmentInteraction(Uri uri) {

}
//endregion

//region PAGE ADAPTER
public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        switch (position) {
            case 0:
                Parcelable wrapped = Parcels.wrap(mydev);
                return IPInfoFragment.newInstance(position + 1, wrapped);
            case 1:
                return devicesFragment.newInstance(position);
            case 2:
                return ToolsSelectionFragment.newInstance(position + 1);
            default:
                Parcelable wrappeddefault = Parcels.wrap(mydev);
                return IPInfoFragment.newInstance(position + 1, wrappeddefault);
        }
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return getText(R.string.title_fragment_IPINFO);
            case 1:
                return getText(R.string.title_fragment_NETSCAN);
            case 2:
                return getText(R.string.title_fragment_UTILITIES);
        }
        return null;
    }
}
//endregion
} 

the method: public Fragment getItem(int position) {} is the inflation of the fragments.

and example of my fragments are all inflated similarly:

public ToolsSelectionFragment() {
    // Required empty public constructor
}

public static ToolsSelectionFragment newInstance(int sectionNumber) {
    ToolsSelectionFragment fragment = new ToolsSelectionFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_tools_selection,container, false);
    initvar(v);
    registerButtonListeners();
    return v;
}

apologies if the formatting is off. Just hoping someone has some input to my issue.

******* UPDATE ******** Due to lack of resolve, here is the complete code for my fragments

IPInfo Fragment:

public class IPInfoFragment extends Fragment implements Serializable, myResultReceiver.Receiver  {


//region UI VARS
TextView tvStatus;
TextView tvPrivateIP;
TextView tvPrivateMAC;
TextView tvConnectionStatus;
TextView tvSSID;
TextView tvNetMask;
TextView tvFrequency;
TextView tvSignal;
TextView tvBroadcast;
TextView tvBSSID;
TextView tvNetIP;
//endregion

public myResultReceiver mReceiver;
public DatabaseHelper dbhelper;

public static String PrivateIP;
public static String PrivateMAC;
public MyDevice mydev;
public Network mynet;
public MyNet personalNet;
public User currentUser;


public final String PREFS_NAME = "userPrefs";
public SharedPreferences myprefs;
public SharedPreferences.Editor editor;



//region FRAGMENT STUFF
private OnFragmentInteractionListener mListener;
private static final String ARG_SECTION_NUMBER = "section_number";
private static final String MYDEV_KEY = "MyDevices_Key";

public IPInfoFragment() {
    // Required empty public constructor
}

/**
 * Returns a new instance of this fragment for the given section
 * number.
 */
public static IPInfoFragment newInstance(int sectionNumber, Parcelable wrappedDev) {
    IPInfoFragment fragment = new IPInfoFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    args.putParcelable(MYDEV_KEY, wrappedDev);

    fragment.setArguments(args);
    return fragment;
}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 

    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_ipinfo, container, false);
    ((MainActivity) getActivity()).setActionBarTitle("IP Info");


    //keep track of current user
    myprefs = getActivity().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    currentUser = new User(myprefs.getString("USERNAME_KEY", "---"), myprefs.getString("EMAIL_KEY", "---"), myprefs.getString("USERPASS_KEY", "---"));


    mydev = Parcels.unwrap(getArguments().getParcelable(MYDEV_KEY));
    new MyDeviceWorker().execute();

    launchNetworkSniffer(1);
    ViewPager mViewPager = (ViewPager) v.findViewById(R.id.container);


    PrivateIP = mydev.getIp();
    PrivateMAC = mydev.getMac();

    initVar(v);

    return v;
}


public void launchNetworkSniffer(int opr) {
    Intent serviceIntent = new Intent(getActivity(), NetHelper.class);

    //setup resultReceiver for service callbacks
    mReceiver = new myResultReceiver(new android.os.Handler());
    mReceiver.setReceiver(this);


    serviceIntent.putExtra(NetHelper.BUNDLE_RECEIVER2, mReceiver);
    serviceIntent.putExtra("OPR", opr);
    getActivity().startService(serviceIntent);
}


@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context; }

}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

//region ASYNCTASK_RUNNERS
private class MyDeviceWorker extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {
        Log.d("BACKGROUND_STARTED", "doing background stufffss**********(^*%fsdf");

        mydev.setListNetworkInterfaces();
        mydev.setInterfacesByDisplayName();
        mydev.getSSIDName();
        mydev.getLocalAddresses("wlan0");

        return null;
    }

    @Override
    protected void onPostExecute(Void v) {

        tvPrivateIP.setText(mydev.getIp().toString());
        tvPrivateMAC.setText(mydev.getMac().toString());
    }

}
//endregion


@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
    Log.d("NET_DATA_RECEIVED", "processing...");

    String newnetjson = resultData.getString("DATA_");
    Log.d("DATA_", newnetjson);

    Gson gson = new Gson();
    mynet = gson.fromJson(newnetjson, Network.class);

    //region DATABASE WORK
    //confusing naming conventions but whatever, It's crunch time.
    personalNet = new MyNet(currentUser.getName(), mynet.getSSID(), mynet.getBSSID(), mynet.getSignal(), mynet.getFrequency(), mynet.getNetIP(), mynet.getBroadcast(), mynet.getNetMask());

    new Thread(new Runnable() {
        @Override
        public void run() {
            dbhelper = new DatabaseHelper(getActivity().getApplicationContext());

            //if returns true, a record exists - so just update teh times connected counter
            if (dbhelper.checkNetworkHistory(currentUser.getName(), mynet.getSSID())) {
                Log.d("DB_IPINFO_OP", "updating user history record for this network");
                dbhelper.updateNetCounter(personalNet);
            }
            else {
                Log.d("DB_IPINFO_OP", "adding new network to user history");
                dbhelper.addUserNetwork(personalNet);
            }

        }
    }).start();



    //region FILL UI
    if (mynet.getState()) { tvConnectionStatus.setText("Connected."); }
    else { tvConnectionStatus.setText("Disconnected"); }

    tvSSID.setText(mynet.getSSID());
    tvBroadcast.setText(mynet.getBroadcast());

    if (mynet.getFrequency() == 0) { tvFrequency.setText("----"); }
    else { tvFrequency.setText(String.valueOf(mynet.getFrequency())); }

    tvBSSID.setText(mynet.getBSSID());

    tvNetIP.setText(mynet.getNetIP());

    if (mynet.getNetMask() == 0)  { tvNetMask.setText("----"); }
    else { tvNetMask.setText(String.valueOf(mynet.getNetMask())); }

    if (mynet.getSignal() == 0) { tvSignal.setText("----"); }
    else { tvSignal.setText(String.valueOf(mynet.getSignal())); }
    //endregion
}

public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction(String title);
}
//endregion


public void initVar(View v) {
    tvPrivateIP = (TextView) v.findViewById(R.id.tvPersonalIP);
    tvPrivateMAC = (TextView) v.findViewById(R.id.tvPersonalMAC);
    tvConnectionStatus = (TextView) v.findViewById(R.id.lblisConnected);
    tvSSID = (TextView) v.findViewById(R.id.tvSSID);
    tvBSSID = (TextView) v.findViewById(R.id.tvBSSID);
    tvNetMask = (TextView) v.findViewById(R.id.tvNetMask);
    tvFrequency = (TextView) v.findViewById(R.id.tvFrequency);
    tvSignal = (TextView) v.findViewById(R.id.tvSignal);
    tvBroadcast = (TextView) v.findViewById(R.id.tvBroadCast);
    tvNetIP = (TextView) v.findViewById(R.id.tvNetIP);

    tvPrivateIP.setText(PrivateIP);
    tvPrivateMAC.setText(PrivateMAC);
}

//region INET-STUFF

//gets ipv6
public String getLocalIpAddress()
{
    try
    {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
        {
            NetworkInterface intf = en.nextElement();


            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
            {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress())
                {
                    return inetAddress.getHostAddress().toString();

                }
            }
        }
    }
    catch (SocketException ex)
    {
        Log.e("SRM", ex.toString());
    }
    return null;
}
//endregion
}

ToolsSelection Fragment

public class ToolsSelectionFragment extends Fragment {

//region UI VARS
Button btnPing;
Button btnDns;
Button btnPortScan;
Button btnTraceRoute;
//endregion


private static final String ARG_SECTION_NUMBER = "section_number";
private OnFragmentInteractionListener mListener;

public ToolsSelectionFragment() {
    // Required empty public constructor
}

public static ToolsSelectionFragment newInstance(int sectionNumber) {
    ToolsSelectionFragment fragment = new ToolsSelectionFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View v = inflater.inflate(R.layout.fragment_tools_selection, container, false);
    initvar(v);
    registerButtonListeners();
    return v;
}


public void initvar(View view) {
    btnPing = (Button) view.findViewById(R.id.btnPing);
    btnDns = (Button) view.findViewById(R.id.btnDns);
    btnPortScan = (Button) view.findViewById(R.id.btnPortScan);
    btnTraceRoute = (Button) view.findViewById(R.id.btnTraceRoute);
}


public void registerButtonListeners() {
    btnPing.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getActivity(), PingActivity.class);
            startActivity(intent);
        }
    });

    btnDns.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getActivity(), DNSActivity.class);
            startActivity(intent);
        }
    });

    btnPortScan.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getActivity(), PortscanActivity.class);
            startActivity(intent);
        }
    });

    btnTraceRoute.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getActivity(), WhoisActivity.class);
            startActivity(intent);
        }
    });
}


// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

/**
 * This interface must be implemented by activities that contain this
 * fragment to allow an interaction in this fragment to be communicated
 * to the activity and potentially other fragments contained in that
 * activity.
 * <p>
 * See the Android Training lesson <a href=
 * "http://developer.android.com/training/basics/fragments/communicating.html"
 * >Communicating with Other Fragments</a> for more information.
 */
public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction(Uri uri);
}
}

DevicesFragment:

public class devicesFragment extends Fragment implements myResultReceiver.Receiver {
public myResultReceiver mReceiver;
OnListFragmentInteractionListener mlistener;
Context context;
MydevicesRecyclerViewAdapter mydevAdapter;

private static ArrayList<Devices> devlist;
SharedPreferences netprefs;

// TODO: Customize parameter argument names
private static final String ARG_COLUMN_COUNT = "column-count";
private int mColumnCount = 1;
private OnListFragmentInteractionListener mListener;


public devicesFragment() {
}
// TODO: Customize parameter initialization
public static devicesFragment newInstance(int columnCount) {
    devicesFragment fragment = new devicesFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_COLUMN_COUNT, columnCount);
    fragment.setArguments(args);
    return fragment;
}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getArguments() != null) {
        mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
    }
}


//TODO: populate devices list with a sharedPreferences list and double check there. also split up subnet into multiple threads to work faster.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_devices_list, container, false);
    ((MainActivity) getActivity()).setActionBarTitle("Net Scan");


    devlist = new ArrayList<>();
    devlist.add(new Devices("TEST_DEVICE", true, "192.168.100.199", "00:00:00:00:00:00", true, "MOBILE", "meeseeks box"));
    devlist.add(new Devices("TEST_DEVICE2", true, "74.16.248.777", "11:11:11:11:11:11", true, "DESKTOP", "meeseeks box"));


    launchNetworkSniffer(0);
    // Set the adapter
    if (view instanceof RecyclerView) {
        Context context = view.getContext();


        RecyclerView recyclerView = (RecyclerView) view;
        if (mColumnCount <= 1) {
            recyclerView.setLayoutManager(new LinearLayoutManager(context));
        } else {
            recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
        }
        mydevAdapter = new MydevicesRecyclerViewAdapter(devlist, mListener);
        recyclerView.setAdapter(mydevAdapter);
    }
    return view;
}


//NetHelper intent service class startup
//discover network info, and get a list of devices
public void launchNetworkSniffer(int opr) {
    Intent serviceIntent = new Intent(getActivity(), NetHelper.class);

    //setup resultReceiver for service callbacks
    mReceiver = new myResultReceiver(new android.os.Handler());
    mReceiver.setReceiver(this);

    serviceIntent.putExtra(NetHelper.BUNDLE_RECEIVER, mReceiver);
    serviceIntent.putExtra("OPR", opr);
    getActivity().startService(serviceIntent);
}

@Override
public void onResume() {
    super.onResume();
    mReceiver.setReceiver(this);
}

//avoid leaks with result receiver

@Override
public void onPause() {
    super.onPause();
    mReceiver.setReceiver(null);
}


@Override
public void onAttach(Context context) {
    super.onAttach(context);

    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception
    try {
        mlistener = (OnListFragmentInteractionListener) context;
    } catch (ClassCastException e) {
        throw new ClassCastException(context.toString()
                + " must implement listener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}



//receiver implemented methods
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
    Log.d("DATA_RECEIVED", "processing...");

    String newdevjson = resultData.getString("DATA_");
    Log.d("DATA_", newdevjson);

    Gson gson = new Gson();
    Devices newd = gson.fromJson(newdevjson, Devices.class);

    if (devlist != null) {
        for (Devices i : devlist) {
            if (i.getIp().equals(newd.getIp())) {
                return;
            }
        }
        Log.d("ADDING_FRAGDEVICE", newd.devName);
        devlist.add(newd);
        mydevAdapter.notifyItemInserted(devlist.size() -1);
        mydevAdapter.notifyDataSetChanged();
    }
}


public interface OnListFragmentInteractionListener {
    // TODO: Update argument type and name
    void onListFragmentInteraction(Devices device);
}
}

REALLY hope to get this solved soon. thanks to those who have attempted so far.

Use FragmentStatePagerAdapter instead of FragmentPagerAdapter

 public  class MyAdapter extends FragmentStatePagerAdapter {
        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        @Override
        public Fragment getItem(int position) {
            return ArrayListFragment.newInstance(position);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM