Commit 79916cc1 authored by Lennart Bader's avatar Lennart Bader
Browse files

Added ShowCaseManager

parent e74f61d6
...@@ -31,5 +31,5 @@ dependencies { ...@@ -31,5 +31,5 @@ dependencies {
compile 'com.android.support:support-v4:25.1.0' compile 'com.android.support:support-v4:25.1.0'
compile 'com.android.support:design:25.1.0' compile 'com.android.support:design:25.1.0'
compile 'com.android.support:cardview-v7:25.1.0' compile 'com.android.support:cardview-v7:25.1.0'
compile 'com.github.wangjiegulu:RapidFloatingActionButton:1.0.3' compile 'com.github.amlcurran.showcaseview:library:5.4.3'
} }
...@@ -9,13 +9,20 @@ import android.support.design.widget.TabLayout; ...@@ -9,13 +9,20 @@ import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView;
import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button;
import com.github.amlcurran.showcaseview.ShowcaseView;
import com.github.amlcurran.showcaseview.targets.Target;
import com.github.amlcurran.showcaseview.targets.ViewTarget;
import de.mytfg.apps.vplan.R; import de.mytfg.apps.vplan.R;
import de.mytfg.apps.vplan.activities.MainActivity; import de.mytfg.apps.vplan.activities.MainActivity;
...@@ -23,6 +30,9 @@ import de.mytfg.apps.vplan.adapters.FragmentHolder; ...@@ -23,6 +30,9 @@ import de.mytfg.apps.vplan.adapters.FragmentHolder;
import de.mytfg.apps.vplan.adapters.ViewPagerAdapter; import de.mytfg.apps.vplan.adapters.ViewPagerAdapter;
import de.mytfg.apps.vplan.logic.PlanLogic; import de.mytfg.apps.vplan.logic.PlanLogic;
import de.mytfg.apps.vplan.objects.Vplan; import de.mytfg.apps.vplan.objects.Vplan;
import de.mytfg.apps.vplan.toolbar.ToolbarManager;
import de.mytfg.apps.vplan.tools.CustomViewTarget;
import de.mytfg.apps.vplan.tools.ShowCaseManager;
public class PlanFragment extends Fragment { public class PlanFragment extends Fragment {
private View view; private View view;
...@@ -204,5 +214,28 @@ public class PlanFragment extends Fragment { ...@@ -204,5 +214,28 @@ public class PlanFragment extends Fragment {
if (tabLayout != null) { if (tabLayout != null) {
tabLayout.setupWithViewPager(viewPager); tabLayout.setupWithViewPager(viewPager);
} }
this.showcase();
} }
private void showcase() {
ShowCaseManager scm = new ShowCaseManager(getContext());
ToolbarManager tbm = ((MainActivity)getActivity()).getToolbarManager();
// scm.show(this, R.id.fab ,"SEARCH", "Such du Spacko!");
Target tab1 = new CustomViewTarget(tbm.getTabs(), 0.25f, 0.5f, getActivity());
Target tab2 = new CustomViewTarget(tbm.getTabs(), 0.75f, 0.5f, getActivity());
Target fab = new ViewTarget(R.id.fab, getActivity());
scm.createChain(this)
.add(tab1, "HEUTE", "Plan für heute")
.add(tab2, "Morgen", "Plan für morgen")
.add(fab, "Suche", "Nach Fächern etc suchen", true)
.showChain();
}
} }
...@@ -7,6 +7,7 @@ import android.support.annotation.Nullable; ...@@ -7,6 +7,7 @@ import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.widget.TextViewCompat; import android.support.v4.widget.TextViewCompat;
import android.support.v7.widget.CardView;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.Html; import android.text.Html;
...@@ -19,6 +20,10 @@ import android.widget.EditText; ...@@ -19,6 +20,10 @@ import android.widget.EditText;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import com.github.amlcurran.showcaseview.ShowcaseView;
import com.github.amlcurran.showcaseview.targets.ActionViewTarget;
import com.github.amlcurran.showcaseview.targets.ViewTarget;
import de.mytfg.apps.vplan.R; import de.mytfg.apps.vplan.R;
import de.mytfg.apps.vplan.activities.MainActivity; import de.mytfg.apps.vplan.activities.MainActivity;
import de.mytfg.apps.vplan.adapters.RecylcerNewsAdapter; import de.mytfg.apps.vplan.adapters.RecylcerNewsAdapter;
...@@ -30,6 +35,7 @@ import de.mytfg.apps.vplan.objects.User; ...@@ -30,6 +35,7 @@ import de.mytfg.apps.vplan.objects.User;
import de.mytfg.apps.vplan.objects.Vplan; import de.mytfg.apps.vplan.objects.Vplan;
import de.mytfg.apps.vplan.toolbar.ToolbarManager; import de.mytfg.apps.vplan.toolbar.ToolbarManager;
import de.mytfg.apps.vplan.tools.ItemOffsetDecoration; import de.mytfg.apps.vplan.tools.ItemOffsetDecoration;
import de.mytfg.apps.vplan.tools.ShowCaseManager;
public class StartFragment extends Fragment { public class StartFragment extends Fragment {
private View view; private View view;
......
package de.mytfg.apps.vplan.tools;
import android.app.Activity;
import android.graphics.Point;
import android.util.Log;
import android.view.View;
import com.github.amlcurran.showcaseview.targets.Target;
/**
* Used to support offsets
*/
public class CustomViewTarget implements Target {
private final View mView;
private int offsetX;
private int offsetY;
private float percX;
private float percY;
private boolean perc;
public CustomViewTarget(View view) {
mView = view;
}
public CustomViewTarget(int viewId, int offsetX, int offsetY, Activity activity) {
this.offsetX = offsetX;
this.offsetY = offsetY;
mView = activity.findViewById(viewId);
}
public CustomViewTarget(View view, float percX, float percY, Activity activity) {
mView = view;
this.percX = percX;
this.percY = percY;
perc = true;
}
@Override
public Point getPoint() {
int[] location = new int[2];
mView.getLocationInWindow(location);
if (perc) {
int midX = mView.getWidth() / 2;
int midY = mView.getHeight() / 2;
int posX = (int) (percX * mView.getWidth());
int posY = (int) (percY * mView.getHeight());
this.offsetX = posX - midX;
this.offsetY = posY - midY;
Log.d("MX", "" + midX);
Log.d("OX", "" + offsetX);
Log.d("PX", "" + percX);
}
int x = location[0] + mView.getWidth() / 2 + offsetX;
int y = location[1] + mView.getHeight() / 2 + offsetY;
return new Point(x, y);
}
}
package de.mytfg.apps.vplan.tools;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import com.github.amlcurran.showcaseview.ShowcaseView;
import com.github.amlcurran.showcaseview.targets.Target;
import com.github.amlcurran.showcaseview.targets.ViewTarget;
import java.util.LinkedList;
import java.util.List;
import de.mytfg.apps.vplan.R;
/**
* Manages storage of settings for easy access
*/
public class ShowCaseManager {
private Context context;
private SharedPreferences preferences;
private List<ChainElement> chain;
private Fragment fragment;
private static ShowcaseView showcaseView;
private class ChainElement {
private String title;
private String text;
private Target target;
private Fragment fragment;
private boolean buttonLeft;
}
public ShowCaseManager(Context context) {
this.context = context;
preferences = context.getSharedPreferences("showcase", Context.MODE_PRIVATE);
}
public void clear(String fragment) {
preferences.edit()
.remove(fragment)
.apply();
}
public void setDone(String fragment) {
preferences.edit()
.putBoolean(fragment, true)
.apply();
}
public boolean isDone(String fragment) {
return preferences.getBoolean(fragment, false);
}
public void show(Fragment fragment, int viewId, String title, String text) {
show(fragment, new ViewTarget(viewId, fragment.getActivity()), title, text);
}
public void show(Fragment fragment, Target target, String title, String text) {
if (isDone(fragment.getClass().toString())) {
return;
}
if (showcaseView != null) {
showcaseView.hide();
}
Button btn = new Button(fragment.getActivity());
btn.setVisibility(View.GONE);
showcaseView = new ShowcaseView.Builder(fragment.getActivity())
.withMaterialShowcase()
.setStyle(R.style.CustomShowcaseTheme)
.replaceEndButton(btn)
.setTarget(target)
.setContentTitle(title)
.setContentText(text)
.hideOnTouchOutside()
.build();
}
public ShowCaseManager createChain(Fragment fragment) {
this.fragment = fragment;
this.chain = new LinkedList<>();
if (showcaseView != null) {
Log.d("SC", "Already there");
showcaseView.hide();
} else {
Log.d("SC", "null (nothing shown)");
}
return this;
}
public ShowCaseManager add(Target target, String title, String text) {
return add(target, title, text, false);
}
public ShowCaseManager add(Target target, String title, String text, boolean buttonLeft) {
ChainElement elem = new ChainElement();
elem.fragment = fragment;
elem.target = target;
elem.title = title;
elem.text = text;
elem.buttonLeft = buttonLeft;
this.chain.add(elem);
return this;
}
public void showChain() {
if (isDone(fragment.getClass().toString())) {
return;
}
if (this.chain.size() > 0) {
ChainElement elem = this.chain.get(0);
this.chain.remove(0);
Button btn = new Button(fragment.getActivity());
btn.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View view) {
showChain();
}
});
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(10, 10, 10, 10);
if (elem.buttonLeft) {
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
} else {
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
}
showcaseView = new ShowcaseView.Builder(fragment.getActivity())
.withNewStyleShowcase()
.setStyle(R.style.CustomShowcaseTheme)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
nextChain();
}
})
.setTarget(elem.target)
.setContentTitle(elem.title)
.setContentText(elem.text)
.build();
showcaseView.setButtonPosition(params);
if (chain.size() == 0) {
showcaseView.setButtonText(context.getString(R.string.hide_showcase));
} else {
showcaseView.setButtonText(context.getString(R.string.next_showcase));
}
}
}
private void nextChain() {
if (chain.size() > 0) {
ChainElement elem = this.chain.get(0);
this.chain.remove(0);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(10, 10, 10, 10);
if (elem.buttonLeft) {
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
} else {
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
}
showcaseView.setButtonPosition(params);
showcaseView.setShowcase(elem.target, true);
if (chain.size() == 0) {
showcaseView.setButtonText(context.getString(R.string.hide_showcase));
}
showcaseView.setContentTitle(elem.title);
showcaseView.setContentText(elem.text);
} else {
showcaseView.hide();
}
}
}
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="@dimen/cardview_spacing" android:padding="@dimen/cardview_spacing"
android:id="@+id/home_login_status_card"
android:layout_marginBottom="@dimen/defaultPadding"> android:layout_marginBottom="@dimen/defaultPadding">
<LinearLayout <LinearLayout
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="colorPrimary">#3F51B5</color> <color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryTransparent">#EE3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color> <color name="colorPrimaryDark">#303F9F</color>
<color name="colorPrimaryLight">#C5CAE9</color> <color name="colorPrimaryLight">#C5CAE9</color>
<color name="colorSecondaryLight">#DFE2F4</color> <color name="colorSecondaryLight">#DFE2F4</color>
......
...@@ -129,4 +129,8 @@ ...@@ -129,4 +129,8 @@
<string name="about_text">This App uses the MyTFG API. All rights reserved.</string> <string name="about_text">This App uses the MyTFG API. All rights reserved.</string>
<string name="about_opensource">Open Source</string> <string name="about_opensource">Open Source</string>
<string name="about_opensource_text">This App is part of the MyTFG Open Source Project.</string> <string name="about_opensource_text">This App is part of the MyTFG Open Source Project.</string>
<!-- SHOWCASE -->
<string name="hide_showcase">Hide</string>
<string name="next_showcase">Next</string>
</resources> </resources>
...@@ -54,4 +54,21 @@ ...@@ -54,4 +54,21 @@
<item name="android:textColor">@color/colorIcons</item> <item name="android:textColor">@color/colorIcons</item>
<item name="android:textAllCaps">false</item> <item name="android:textAllCaps">false</item>
</style> </style>
<style name="CustomShowcaseTheme" parent="ShowcaseView.Light">
<item name="sv_backgroundColor">@color/colorPrimaryTransparent</item>
<item name="sv_showcaseColor">@color/colorAccent</item>
<item name="sv_titleTextAppearance">@style/CustomTitle</item>
<item name="sv_detailTextAppearance">@style/CustomText</item>
<item name="sv_buttonText">Hide</item>
<item name="sv_tintButtonColor">false</item>
</style>
<style name="CustomTitle" parent="TextAppearance.ShowcaseView.Title">
<item name="android:textColor">@color/colorAccent</item>
</style>
<style name="CustomText" parent="TextAppearance.ShowcaseView.Detail.Light">
<item name="android:textColor">@color/colorIcons</item>
</style>
</resources> </resources>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment