简体   繁体   English

初学者,使用导航抽屉切换时保持片段状态

[英]Beginner, Maintaining Fragment State When switching using Navigation Drawer

I'm a beginner with java and android development but managed to create a navigation drawer activity which switches between five fragment with ListViews using AsycTask. 我是Java和android开发的初学者,但是设法创建了一个导航抽屉活动,该活动使用AsycTask在具有ListViews的五个片段之间切换。 The AsycTask starts again when ever I switch between the fragments. 每当我在片段之间切换时,AsycTask就会再次启动。 I have gone through many of the post here but none seems to work. 我在这里浏览了很多帖子,但是似乎都没有用。 Any help. 任何帮助。

Here is My Navigation Drawer Activity 这是我的导航抽屉活动

public class Home extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {


private static String website = "https://www.website.com", fbPage = "https://www.facebook.com",
        twitter = "https://twitter.com",

private android.support.v4.app.FragmentManager fragmentManager;
private android.support.v4.app.FragmentTransaction fragmentTransaction;


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

        getSupportFragmentManager().beginTransaction()
                .add(R.id.fragment_holder, new HomeFragment(), "Home Fragment")
                .commit();

    fragmentManager = getSupportFragmentManager();

}

private void customNavgation() {
    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    navigationView.getMenu().getItem(0).setChecked(true);
}

}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.nav_home) {

        HomeFragment homeFragment = new HomeFragment();
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_holder, homeFragment, "HomeFragment");
        fragmentTransaction.commit();

    } else if (id == R.id.nav_message) {

        MessageFragment messageFragment = new MessageFragment();
            fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.add(R.id.fragment_holder, messageFragment, "MessageFragment");
            fragmentTransaction.commit();

    } else if (id == R.id.nav_word) {

        WordFragment wordFragment = new WordFragment();
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_holder, wordFragment, "WordFragment");
        fragmentTransaction.commit();

    } else if (id == R.id.nav_events) {

        EventsFragment eventsFragment = new EventsFragment();
            fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.add(R.id.fragment_holder, eventsFragment, "EventsFrangment");
            fragmentTransaction.commit();

    } else if (id == R.id.nav_service) {

        ServiceFragment serviceFragment = new ServiceFragment();
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_holder, serviceFragment, "Service Fragment");
        fragmentTransaction.commit();

    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

And here is one of my Fragment class 这是我的Fragment类之一

public class EventsFragment extends Fragment {

ArrayList<EventsFields> eventsFieldsList;
private ListView eventlist;

static final String EVENT_LINK = "http:www.website.com";
private ProgressBar pb;
private View view;


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

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_events, container, false);

        eventlist = (ListView) view.findViewById(R.id.event_frag_listView);
        pb = (ProgressBar) view.findViewById(R.id.progressBar);
        pb.setVisibility(View.INVISIBLE);

        if (isOnline()) {
            requestData(EVENT_LINK);
        } else {
            Toast.makeText(EventsFragment.this.getActivity(), "No Internet Connection", Toast.LENGTH_LONG).show();
        }

    return view;
}


protected void updateDisplay() {
    EventsListAdapter adapter = new EventsListAdapter(EventsFragment.this.getActivity(), R.layout.event_list_layout, eventsFieldsList);
    eventlist.setAdapter(adapter);
    eventlist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Intent intent = new Intent(EventsFragment.this.getActivity(), EventDetail.class);
            EventsFields selectedEvent = eventsFieldsList.get(position);
            intent.putExtra("selectedEvent", selectedEvent);
            startActivity(intent);
        }
    });
}


private void requestData(String uri) {
    MyTask task = new MyTask();
    task.execute(uri);
}


protected boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netinfo = cm.getActiveNetworkInfo();

    if (netinfo != null && netinfo.isConnectedOrConnecting()) {
        return true;
    } else {
        return false;
    }
}

public class MyTask extends AsyncTask<String, String, ArrayList<EventsFields>> {

    @Override
    protected void onPreExecute() {
        pb.setVisibility(View.VISIBLE);
    }

    @Override
    protected ArrayList<EventsFields> doInBackground(String... params) {

        String data = HttpManager.getData(params[0]);
        eventsFieldsList = EventsJsonParser.parseFeed(data);

        return eventsFieldsList;
    }

    @Override
    protected void onPostExecute(ArrayList<EventsFields> results) {


        pb.setVisibility(View.INVISIBLE);

        if (results == null) {
            Toast.makeText(EventsFragment.this.getActivity(), "Web service not available", Toast.LENGTH_LONG).show();
            return;
        }
        eventsFieldsList = results;
        updateDisplay();
    }

}

JsonPaser Class JsonPaser类

public class EventsJsonParser {

public static ArrayList<EventsFields> parseFeed(String content) {

    try {

        JSONArray ar = new JSONArray(content);
        ArrayList<EventsFields> eventList = new ArrayList<>();

        for (int i = 0; i < ar.length(); i++) {

            JSONObject obj = ar.getJSONObject(i);

            EventsFields events = new EventsFields(null);

            events.setId(obj.getInt("id"));
            events.setEventName(obj.getString("EventName"));
            events.setStartDate(obj.getString("StartDate"));
            events.setEventDesc(obj.getString("EventDesc"));
            events.setTime(obj.getString("Time"));
            events.setVenue(obj.getString("Venue"));
            eventList.add(events);
        }

        return eventList;

    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }

}

Thanks 谢谢

One approach is to persist the data and then don't call the AsyncTask if you've already received the data. 一种方法是保留数据,如果已经收到数据,则不要调用AsyncTask

@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putParcelableArrayList("eventsFieldsList", eventsFieldsList);
    super.onSaveInstanceState(outState);
}

then in onCreateView() : 然后在onCreateView()

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                     Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_events, container, false);

        eventlist = (ListView) view.findViewById(R.id.event_frag_listView);
        pb = (ProgressBar) view.findViewById(R.id.progressBar);
        pb.setVisibility(View.INVISIBLE);

        if (savedInstanceState != null) {
            eventsFieldsList = savedInstanceState.getParcelableArrayList("eventsFieldsList");
        }

        if (eventsFieldList == null) {
            if (isOnline()) {
                requestData(EVENT_LINK);
            } else {
                Toast.makeText(EventsFragment.this.getActivity(), "No Internet Connection", Toast.LENGTH_LONG).show();
            }
        }

    return view;
}

You would need to make your EventsFields class implement Parcelable . 你需要让你的EventsFields类实现Parcelable There are lots of online tutorials and SO answers on this. 关于这一点,有很多在线教程和答案。 If you have problems with implementing Parcelable , post a new question. 如果您在实施Parcelable遇到问题,请发布新问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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