Skip to content
This repository was archived by the owner on Dec 17, 2020. It is now read-only.

Commit 2f9f73b

Browse files
committed
- Added support for specialized Fragment TaskManager;
- Added a specialized task handling activity (TaskActivity) and fragment (TaskFragment) class; - Moved some internally used classes to the "internal" package; - Added a TaskManagerLifeCycleProxy class to implement the TaskActivity or TaskFragment behavior on any Fragment or AppCompatActivity which is already extended by some other library or something like that; - Some other small API improvements;
1 parent dc399c6 commit 2f9f73b

17 files changed

+722
-64
lines changed

demo/src/main/AndroidManifest.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
android:label="@string/app_name"
1010
android:supportsRtl="true"
1111
android:theme="@style/AppTheme">
12+
13+
<activity
14+
android:name=".ActivityWithFragments"
15+
android:label="@string/app_name"
16+
android:theme="@style/AppTheme">
17+
</activity>
18+
1219
<activity
1320
android:name=".Main"
1421
android:label="@string/app_name"
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
package org.neotech.app.retainabletasksdemo;
2+
3+
import android.content.res.Configuration;
4+
import android.os.Bundle;
5+
import android.support.design.widget.NavigationView;
6+
import android.support.v4.app.Fragment;
7+
import android.support.v4.app.FragmentManager;
8+
import android.support.v4.app.FragmentTransaction;
9+
import android.support.v4.view.GravityCompat;
10+
import android.support.v4.widget.DrawerLayout;
11+
import android.support.v7.app.ActionBarDrawerToggle;
12+
import android.support.v7.app.AppCompatActivity;
13+
import android.util.Log;
14+
import android.view.MenuItem;
15+
import android.view.View;
16+
17+
import java.util.HashMap;
18+
19+
public class ActivityWithFragments extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
20+
21+
private static final String[] FRAGMENT_TAGS = new String[]{"Fragment 1", "Fragment 2", "Fragment 3"};
22+
23+
private FragmentAdapter adapter;
24+
private ActionBarDrawerToggle toggle;
25+
26+
@Override
27+
protected void onCreate(Bundle savedInstanceState) {
28+
super.onCreate(savedInstanceState);
29+
setContentView(R.layout.activity_with_fragments);
30+
31+
adapter = new FragmentAdapter(getSupportFragmentManager(), R.id.fragment_container, 3);
32+
for (String FRAGMENT_TAG : FRAGMENT_TAGS) {
33+
adapter.addFragment(FRAGMENT_TAG, TestFragment.class);
34+
}
35+
36+
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
37+
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
38+
toggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
39+
drawerLayout.addDrawerListener(toggle);
40+
NavigationView drawer = (NavigationView) findViewById(R.id.nav_view);
41+
drawer.setNavigationItemSelectedListener(this);
42+
drawer.getHeaderView(0).setVisibility(View.GONE);
43+
44+
if(savedInstanceState == null){
45+
adapter.setCurrentFragment(FRAGMENT_TAGS[0]);
46+
drawer.setCheckedItem(R.id.nav_fragment_1);
47+
setTitle(FRAGMENT_TAGS[0]);
48+
} else {
49+
setTitle(adapter.getCurrentFragment().getTag());
50+
}
51+
}
52+
53+
public void setTitle(String title){
54+
getSupportActionBar().setTitle(title);
55+
}
56+
57+
@Override
58+
protected void onPostCreate(Bundle savedInstanceState) {
59+
super.onPostCreate(savedInstanceState);
60+
toggle.syncState();
61+
}
62+
63+
@Override
64+
public void onBackPressed() {
65+
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
66+
if (drawer.isDrawerOpen(GravityCompat.START)) {
67+
drawer.closeDrawer(GravityCompat.START);
68+
} else {
69+
super.onBackPressed();
70+
}
71+
}
72+
73+
@Override
74+
public void onConfigurationChanged(Configuration newConfig) {
75+
super.onConfigurationChanged(newConfig);
76+
toggle.onConfigurationChanged(newConfig);
77+
}
78+
79+
@Override
80+
public boolean onOptionsItemSelected(MenuItem item) {
81+
final int id = item.getItemId();
82+
83+
if (id == android.R.id.home) {
84+
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
85+
final NavigationView navigation = (NavigationView) findViewById(R.id.nav_view);
86+
if (drawer.isDrawerOpen(navigation)) {
87+
drawer.closeDrawer(navigation);
88+
} else {
89+
drawer.openDrawer(navigation);
90+
}
91+
return true;
92+
}
93+
return super.onOptionsItemSelected(item);
94+
}
95+
96+
@SuppressWarnings("StatementWithEmptyBody")
97+
@Override
98+
public boolean onNavigationItemSelected(MenuItem item) {
99+
// Handle navigation view item clicks here.
100+
int id = item.getItemId();
101+
102+
if (id == R.id.nav_fragment_1) {
103+
adapter.setCurrentFragment(FRAGMENT_TAGS[0]);
104+
setTitle(FRAGMENT_TAGS[0]);
105+
} else if (id == R.id.nav_fragment_2) {
106+
adapter.setCurrentFragment(FRAGMENT_TAGS[1]);
107+
setTitle(FRAGMENT_TAGS[1]);
108+
} else if (id == R.id.nav_fragment_3) {
109+
adapter.setCurrentFragment(FRAGMENT_TAGS[2]);
110+
setTitle(FRAGMENT_TAGS[2]);
111+
}
112+
113+
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
114+
drawer.closeDrawer(GravityCompat.START);
115+
return true;
116+
}
117+
118+
@Override
119+
protected void onStart() {
120+
super.onStart();
121+
}
122+
123+
public static class FragmentAdapter {
124+
125+
private final HashMap<String, Class<? extends Fragment>> fragments;
126+
127+
private final FragmentManager fragmentManager;
128+
private final int containerId;
129+
130+
public FragmentAdapter(FragmentManager fragmentManager, int containerViewId){
131+
this(fragmentManager, containerViewId, 4);
132+
}
133+
134+
public FragmentAdapter(FragmentManager fragmentManager, int containerViewId, int initialSize){
135+
this.fragments = new HashMap<>(initialSize);
136+
this.fragmentManager = fragmentManager;
137+
this.containerId = containerViewId;
138+
}
139+
140+
public void addFragment(String tag, Class<? extends Fragment> fragmentClass){
141+
fragments.put(tag, fragmentClass);
142+
}
143+
144+
public int size(){
145+
return fragments.size();
146+
}
147+
148+
public Fragment getFragment(String tag){
149+
return fragmentManager.findFragmentByTag(tag);
150+
}
151+
152+
public Fragment getCurrentFragment(){
153+
return fragmentManager.findFragmentById(containerId);
154+
}
155+
156+
public Fragment setCurrentFragment(String tag){
157+
//Retrieve the existing fragment or create a new one.
158+
Fragment fragment = fragmentManager.findFragmentByTag(tag);
159+
if(fragment == null) {
160+
fragment = instantiate(fragments.get(tag));
161+
}
162+
163+
//Check if the currently visible fragment is not equal to the fragment we're about to show.
164+
if(fragment.equals(fragmentManager.findFragmentById(containerId))){
165+
Log.i("FragmentAdapter", "Fragment '" + tag + "' not shown because it's already visible.");
166+
return fragment;
167+
}
168+
169+
//Show the new fragment.
170+
fragmentManager.beginTransaction()
171+
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
172+
.replace(containerId, fragment, tag)
173+
.commit();
174+
return fragment;
175+
}
176+
177+
private static Fragment instantiate(Class<? extends Fragment> classType) {
178+
try {
179+
return classType.newInstance();
180+
} catch(Exception e) {
181+
throw new Fragment.InstantiationException("Unable to instantiate fragment " + classType.getName() + ": make sure class name exists, is public, and has an empty constructor that is public", e);
182+
}
183+
}
184+
}
185+
}

demo/src/main/java/org/neotech/app/retainabletasksdemo/Main.java

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package org.neotech.app.retainabletasksdemo;
22

3-
import android.annotation.SuppressLint;
43
import android.content.Intent;
54
import android.net.Uri;
65
import android.os.Bundle;
7-
import android.support.design.widget.FloatingActionButton;
6+
import android.support.annotation.NonNull;
87
import android.support.design.widget.Snackbar;
98
import android.support.v4.app.DialogFragment;
10-
import android.support.v7.app.AppCompatActivity;
119
import android.support.v7.widget.Toolbar;
1210
import android.view.View;
1311
import android.widget.Button;
@@ -17,10 +15,10 @@
1715
import org.neotech.app.retainabletasksdemo.tasks.SimpleTask;
1816
import org.neotech.app.retainabletasksdemo.tasks.TaskWithoutCallback;
1917
import org.neotech.library.retainabletasks.Task;
18+
import org.neotech.library.retainabletasks.TaskActivity;
2019
import org.neotech.library.retainabletasks.TaskExecutor;
21-
import org.neotech.library.retainabletasks.TaskManager;
2220

23-
public class Main extends AppCompatActivity implements View.OnClickListener, Task.AdvancedCallback, OnAlertDialogClickListener {
21+
public class Main extends TaskActivity implements View.OnClickListener, Task.AdvancedCallback, OnAlertDialogClickListener {
2422

2523
private static final String TASK_RETAIN_UI_STATE = "retain-ui-state";
2624
private static final String TASK_PROGRESS = "progress-dialog";
@@ -36,6 +34,7 @@ protected void onCreate(Bundle savedInstanceState) {
3634
setContentView(R.layout.activity_main);
3735
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
3836

37+
findViewById(R.id.button_open_fragment_activity).setOnClickListener(this);
3938
findViewById(R.id.fab).setOnClickListener(this);
4039
findViewById(R.id.button_no_ui_task).setOnClickListener(this);
4140
findViewById(R.id.button_progress_task).setOnClickListener(this);
@@ -44,22 +43,20 @@ protected void onCreate(Bundle savedInstanceState) {
4443
retainUserInterfaceButton.setOnClickListener(this);
4544
}
4645

46+
/*
4747
@Override
4848
protected void onStart() {
4949
super.onStart();
5050
progressDialog = ProgressDialog.getExistingInstance(getSupportFragmentManager(), DIALOG_PROGRESS);
51-
getTaskManager().attachListener(TASK_PROGRESS, this);
51+
}
52+
53+
getTaskManager().attach(TASK_PROGRESS, this);
5254
5355
54-
getTaskManager().attachListener(TASK_RETAIN_UI_STATE, new TaskManager.TaskAttachListener() {
56+
getTaskManager().attach(TASK_RETAIN_UI_STATE, new TaskManager.TaskAttachListener() {
5557
@Override
5658
public Task.Callback onPreAttach(Task<?, ?> task) {
57-
/**
58-
* the onPreAttach method will only be called if the task did not deliver its result
59-
* and thus is still available/referenced by the TaskManger.
60-
*
61-
* At this point the UI can be restored to the "task is running" state.
62-
*/
59+
6360
if (!task.isResultDelivered()) { //This call isn't necessary.
6461
retainUserInterfaceButton.setEnabled(false);
6562
retainUserInterfaceButton.setText("" + task.getLastKnownProgress());
@@ -68,6 +65,26 @@ public Task.Callback onPreAttach(Task<?, ?> task) {
6865
}
6966
});
7067
}
68+
*/
69+
70+
@Override
71+
public Task.Callback onPreAttach(@NonNull Task<?, ?> task) {
72+
if(task.getTag().equals(TASK_RETAIN_UI_STATE)){
73+
/**
74+
* the onPreAttach method will only be called if the task did not deliver its result
75+
* and thus is still available/referenced by the TaskManger.
76+
*
77+
* At this point the UI can be restored to the "task is running" state.
78+
*/
79+
if (!task.isResultDelivered()) { //This call isn't necessary.
80+
retainUserInterfaceButton.setEnabled(false);
81+
retainUserInterfaceButton.setText("" + task.getLastKnownProgress());
82+
}
83+
} else if(task.getTag().equals(TASK_PROGRESS)){
84+
progressDialog = ProgressDialog.getExistingInstance(getSupportFragmentManager(), DIALOG_PROGRESS);
85+
}
86+
return this;
87+
}
7188

7289
@Override
7390
public void onClick(View v) {
@@ -88,13 +105,11 @@ public void onClick(View v) {
88105
CountDownTask task = new CountDownTask(TASK_RETAIN_UI_STATE, 10);
89106
getTaskManager().execute(task, this);
90107
retainUserInterfaceButton.setEnabled(false);
108+
} else if(id == R.id.button_open_fragment_activity){
109+
startActivity(new Intent(this, ActivityWithFragments.class));
91110
}
92111
}
93112

94-
public TaskManager getTaskManager(){
95-
return TaskManager.getActivityTaskManager(getSupportFragmentManager());
96-
}
97-
98113
@Override
99114
public void onPreExecute(Task<?, ?> task) {
100115
if(task.getTag().equals(TASK_PROGRESS)) {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.neotech.app.retainabletasksdemo;
2+
3+
import android.os.Bundle;
4+
import android.support.annotation.NonNull;
5+
import android.support.annotation.Nullable;
6+
import android.support.design.widget.Snackbar;
7+
import android.view.LayoutInflater;
8+
import android.view.View;
9+
import android.view.ViewGroup;
10+
import android.widget.Button;
11+
12+
import org.neotech.app.retainabletasksdemo.tasks.CountDownTask;
13+
import org.neotech.library.retainabletasks.Task;
14+
import org.neotech.library.retainabletasks.TaskFragment;
15+
16+
/**
17+
* Created by Rolf on 3-3-2016.
18+
*/
19+
public class TestFragment extends TaskFragment implements View.OnClickListener, Task.AdvancedCallback {
20+
21+
private Button button;
22+
23+
@Nullable
24+
@Override
25+
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
26+
View view = inflater.inflate(R.layout.fragment_test, container, false);
27+
button = (Button) view.findViewById(R.id.button_task);
28+
button.setOnClickListener(this);
29+
return view;
30+
}
31+
32+
@Override
33+
public void onClick(View v) {
34+
CountDownTask task = new CountDownTask("CountDownTask", 10);
35+
getTaskManager().execute(task, this);
36+
button.setEnabled(false);
37+
}
38+
39+
@Override
40+
public Task.Callback onPreAttach(@NonNull Task<?, ?> task) {
41+
button.setEnabled(false);
42+
button.setText("" + task.getLastKnownProgress());
43+
return this;
44+
}
45+
46+
@Override
47+
public void onPreExecute(Task<?, ?> task) {
48+
49+
}
50+
51+
@Override
52+
public void onPostExecute(Task<?, ?> task) {
53+
button.setEnabled(true);
54+
button.setText(R.string.task_fragment_based);
55+
Snackbar.make(getView(), getString(R.string.toast_task_finished, getString(R.string.task_fragment_based)), Snackbar.LENGTH_LONG).show();
56+
}
57+
58+
@Override
59+
public void onCanceled(Task<?, ?> task) {
60+
61+
}
62+
63+
@Override
64+
public void onProgressUpdate(Task<?, ?> task, Object progress) {
65+
button.setText("" + (int) progress);
66+
}
67+
}

0 commit comments

Comments
 (0)