What is a recommended Android utility class collection? - android

I often find myself writing very similar code across projects. And more often than not, I copy stuff over from old projects.
Things like:
Create images with round corners
read density into a static variable & re-use. 4 lines..
disable / hide multiple views / remote views at once. Example:
}
public static void disableViews(RemoteViews views, int... ids) {
for (int id : ids) {
views.setInt(id, SET_VISIBILITY, View.GONE);
}
}
public static void showViews(RemoteViews views, int... ids) {
for (int id : ids) {
views.setInt(id, SET_VISIBILITY, View.VISIBLE);
}
}
I'd love to package these kind of functions into 1 letter / 2 letter class names, i.e. V.showViews(RemoteViews views, int... ids) would be easy to write & remember I hope.
I'm searching for Github recommendations, links and if nothing is found, I perhaps will start a small project on github to collect.

You could take a look at https://github.com/kaeppler/droid-fu, it might be worth to study and eventually extend it. It's a utility framework not only for views but covering other aspects as well.

Related

How to improve Android MVVM Tic-Tac-Toe

I was following this tutorial (https://academy.realm.io/posts/eric-maxwell-mvc-mvp-and-mvvm-on-android/) implementing different patterns (MVC, MVP and MVVM) in Kotlin for a Tic Tac Toe game. At the MVVM part, the example does the following:
public class TicTacToeViewModel implements ViewModel {
private Board model;
public final ObservableArrayMap<String, String> cells = new ObservableArrayMap<>();
public final ObservableField<String> winner = new ObservableField<>();
public TicTacToeViewModel() {
model = new Board();
}
[...]
public void onClickedCellAt(int row, int col) {
Player playerThatMoved = model.mark(row, col);
cells.put("" + row + col, playerThatMoved == null ?
null : playerThatMoved.toString());
winner.set(model.getWinner() == null ? null : model.getWinner().toString());
}
[...]
}
Considering that the model, of class Board, already has an attribute board (that is an Array < Array < Cell > >), what's the point for replicate that board with other variable at the TicTacToeViewModel? Is not possible refer to the model board directly with an LiveData or Observable class? Same for the winner
I've saw as well many implementations on Github doing the same, and I am wondering if that's happening due to heritance of the article or in fact has to be this way when the data is kind of complex (a 2D array in this particular case)
I'll appreciate any comments or thoughts on this. Thanks in advance!
I skimmed the tutorial and the github page, and in short I would recommend not following that tutorial :)
Looking at the source code on github, it's clearly an unfinished project. For example, the one layout in the entire project just has a "Hello, world!" TextView in it, which is boilerplate code you get just for creating an Android project...
But to answer your question in a more general sense, you don't necessarily need redundant data structures to represent the board. One reason you might want them is to differentiate between what is displayed to the user versus what the app uses to track the state of the game. For example, the user sees 'O's and 'X's, but perhaps your ViewModel or backing data structure tracks the board as a binary string for the sake of memory and performance (imagine scaling the game out to a much larger board.) But you could probably just create a function to convert the underlying data to a user-friendly format for display, without the need for redundant data structures.

Displaying settings internally represented with sections in Android Listview

I'm writing an application for iOS and Android in parallell and I am facing a small problem.
I am displaying a list of settings to the user and the settings data is internally represented in settings for section, like this:
Section
Section object
Section object
Section
Section object
etc.
In iOS, when the user clicks a setting object, or when the system wants to paint the view for it, it calls a method with an NSIndexPath object. For example:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
and the sections are handled automatically.
In Android, the listviews are "flattened", lacking better terminology. So that a method is called only with a row index:
public Object getItem(int position);
Now it is actually a quite hard problem to solve trying to represet sections directly in the Adapter (MySettingsAdapter extends BaseAdapter).
Right now this problem is solved by flattening the entire underlaying data structure, but it's a lot of duplicated code for almost nothing. The nicer solution I can think of is to do something like the following in my MySettingsAdapter:
class MySettingsAdapter extends BaseAdapter {
MyInternalDataStructure settingsData;
int sections;
int rowsForSection[sections];
public MySettingsAdapter (MyInternalDataStructure settingsData) {
this.settingsData = settingsData;
this.sections = settingsData.sections;
for (int i = 0; i < sections; i++) {
rowsForSection[i] = settingsData.settingsInSection[i].size();
}
}
#Override
public Object getItem(int position) {
int sectionFromPostion;
int rowFromPosition;
// Calculate section and row here...
return settingsData.getSetting(sectionFromPostion, rowFromPosition);
}
}
And I just can't get the calculations for sectionFromPostion and rowFromPostion right...
Unfortunately Android does not have quite the same ability in regards to sections as you can achieve with the UITableView. However Android does provide a solution, the ExpandableListView. While similar to a ListView it works a bit differently and interacts with a different type of adapter.
Android provides the SimpleExpandableListAdapter that you can use with the ExpandableListView. I'll warn you now. It's clunky and pretty restricting. Additionally, it requires you to organize your data into a List of Maps which in itself can be a pain to do.
Alternatively, you can create your own adapter for the ExpandableListView by implementing the BaseExpandableListAdapter. It's very similar to implementing the BaseAdapter. It just has a few extra bells and whistles to support a tier like structure.
Basically all these Expandable...[foo] classes introduce the idea of having a group (the section) and children (the data under a section). Instead of having an index to the data in your adapter, you'll have a groupPosition and a childPosition. Meanwhile the ExpandableListView has this sorta murky middle notion of positions as it works with group/child positions, packed positions, and flattened positions.
As a side note. Depending on how your data is organized, I'd suggest checking out the Rolodex Adapters found in this 3rd party library. They are meant to make working with ExpandableListViews easier and has plenty of code examples and a demo app to help get you going.

Handling arraylists created in a custom class (newbie confusion)

Basically, I need to add items to the arraylist. Am I correct in using a separate class (this is in part what I am practicing here) or is that a stupid idea because it is basically just an arraylist. I thought I would create a class because I want to randomise additions to it, etc. Alternately, since it is just an arraylist class, should I use "extends arraylist" or something similar??? Code examples most welcome. I am obviously missing some crucial programming theory here. Thank you.
NOTE I have removed what I think is unrelated code
I have a main:
public class cgame2 extends Activity {
private ArrayList<Integer> cToChooseFromImages; // clear image list
colourlist colourlistused = new colourlist();
colourlist userscolourlist = new colourlist();
....truncated....towards the end of my code I have......
colourlistused.randomaddnewitem();
And I have a class (called colourlist):
import java.util.ArrayList;
import java.util.Random;
import android.util.Log;
public class colourlist {
private ArrayList<Integer> clist;
private int picked;
int imagetodisp;
public colourlist() {
}
public void randomaddnewitem() {
Random randomtouse = new Random(System.nanoTime());
picked = randomtouse.nextInt(3);
clist.add(picked); // this is where the program crashes according to log info
}
public void addnewitem(int itemtoadd) {
clist.add(itemtoadd);
}
.....etc.....
If you're adding functionality to ArrayList, the best way is just the way you have done it.
Create a member ArrayList of your class and create functions to extend the behavior. This is called Composition.
Contrast with Inheritance, or creating a subclass of ArrayList, which can create more problems by unnecessarily coupling your implementation to ArrayList.
Don't forget to initialize the list. The best way would be:
List<Integer> clist = new ArrayList<Integer>();
Use the interface List to make your code more flexible if you choose to change the specific list implementation later.
Creating a class for your array list isn't a bad idea, classes in and of themselves are data structures, and this will allow to manipulate the data easier. By having the array list in it's own class, you will be able to get it, set it, send it, alter it, etc, with ease. However, when it comes to creating classes, you generally want to create classes that could be considered objects. If you are a beginning programmer, I would recommend exploring and researching object oriented analysis and design, as that will help you determine what should and shouldn't be classes.
And, as others have pointed out, make sure you initialize your array list:
List<Integer> clist = new ArrayList<Integer>();
As for extending ArrayList vs. List, I would use ArrayList because 1. It has all the methods and functionality of List (because is is an implementation of List) and 2. It is backed by an array, which is what you are using. Just my preference, feel free to do some research and figure out what is going to work best for what you need; a List may be all you need, in which case, you should use that.
One other things I will point out, since it looks like you are creating a game, is that if you are going to pass and object, in your case and ArrayList, you are going to want to get familiar with the Parcelable interface. It is what will allow you to pass data from one activity to another. Here is a link that will get you started, along with a tutorial that might offer some insight to what is needed:
Tutorial for Parceleable:
http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/
Developer Info:
http://developer.android.com/reference/android/os/Parcelable.html
Best of luck!

Show a fraction of numbers, one above the other, like on Libreoffice

Libreoffice (and other apps like Latex) allows you to use some kind of script language to show really cool mathematical formulas.
I need to use a view (probably a textView) that will be able to shows such formulas, and fractions in particular.
For example "x over y" would look like:
x
-
y
and so on.
Is there any such solution for this on Android? Maybe a library (with license similar to Apache or better) that allows you to write such things?
You could easily extend the view class and replicate this with two TextViews and an ImageView. Probably not the most efficient way of doing this but certainly pretty easy.
Some sudo code but you get the idea..
public class FractionView extends View {
private TextView top;
private Textview bottom;
private ImageView line;
public FractionView(Context context) {
// instantiate the views
}
// TODO add methods to update the text, possibly update positions as well, more stuff?
}

visual indication of over scroll in android

I am trying to add some visual indication, that there are no more pages in the desired fling direction in the ViewPager. However I am struggling to find a place, where to put relevant code.
I have tried extending ViewPager class with following code, but the Toast is not displaying (ev.getOrientation() returns always 0). I have also tried the same with history points, but ev.getHistorySize() returns also 0.
What am I missing?
Class example:
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* #see android.support.v4.view.ViewPager#onTouchEvent(android.view.MotionEvent)
*/
#Override
public boolean onTouchEvent(MotionEvent ev) {
boolean result = super.onTouchEvent(ev);
switch (ev.getAction() & MotionEventCompat.ACTION_MASK) {
case MotionEvent.ACTION_MOVE:
if (ev.getOrientation() > 0) {
Toast.makeText(getContext(), "left", 0).show();
}
}
return result;
}
}
If you look at the v4 support library you will see there's a class used by ViewPager called EdgeEffectCompat (this provides the glow effect when you reach the beginning or end of a view pager in ICS+) If you look at the implementation in the compat library you will see that it has an if-statement to see if the build version is 14+ (ICS) or not. If it is, then it ends up eventually (if you trace long enough) using the normal EdgeEffect class that was inroduced in ICS. Otherwise it uses BaseEdgeEffectImpl which basically has nothing in it.
If you want, you can make your own custom ViewPager that uses EdgeEffect of your own. You can look at the android source code to see how they implemented EdgeEffect here which you can pretty much copy (just make sure to copy the overscroll_edge and overscroll_glow drawables in the AOSP /res/drawable directories to your own project since they are internal to android) or go ahead and create your own version.
Good luck.
(By the way, that's how they create the cool looking edge tilt effect in the launcher menu on ICS... so you can pretty much be as creative as you want with this ;)
I was trying to get the exact same effect that was asked in this question. I struggle with it and then I read #wnafee answer (I couldn't do it with out it).
But then I struggle to implement what was sound pretty simple from the answer.
I had so much trouble with implementing it, that I might didn't understand the answer correctly, but there were too many issues of inaccessible APIs since I wasn't working in the same package of the Compatibility library.
After I tried some approaches (none of them succeeded, and they were pretty complicated) I went to a slightly different direction, and now it works like a charm. I used some reflection, for the ones who never used it, don't worry it is really the basic of reflection.
I'm not sure if it's the best solution out there, but it worked for me, so if you would like to use it you are welcome. Please read Wnafee example since it explains some of the stuff that I did.
In order to accomplish this task you should just follow my three parts solution. (Will take you between 3-10 minutes)
Part I:
As Wnafee said I just made my own EdgeEffect class by copy paste the source code from here,
(just make sure to copy the overscroll_edge and overscroll_glow
drawables in the AOSP /res/drawable directories to your own project
since they are internal to android)
I only did 2 really small changes:
I declare that the class extends EdgeEffectCompat (I called my class EdgeEffectForEarlyVersions). public class EdgeEffectForEarlyVersions extends EdgeEffectCompat. The reason for doing this change is that the mLeftEdge and mRightEdge are of the type EdgeEffectCompat.
At the first line of the constructor of "my" new class I added a call to the parent constructor super(context);. Since there is no default constructor to EdgeEffectCompat you have to Explicitly call the constructor.
Part II
Besides that I wrote the another function. The purpose of the function is that in case of an early version (before ICS) we would like to use the EdgeEffectForEarlyVersions that we just copied. In order to get that purpose I used reflection.
This is the function:
private static void changeEdgeEffectCompactOnEarlyVersions(ViewPager viewPager, Context context)
{
/* In case that the version is earlier than 14 there is only empty implementation for the edge effect, therefore we change it.
* for more information look on the following links:
* 1. http://stackoverflow.com/questions/10773565/visual-indication-of-over-scroll-in-android
* 2. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/view/ViewPager.java#ViewPager.0mLeftEdge
* 3. http://grepcode.com/file/repo1.maven.org/maven2/com.google.android/support-v4/r7/android/support/v4/widget/EdgeEffectCompat.java#EdgeEffectCompat
*/
if (Build.VERSION.SDK_INT < 14)
{
try
{
Class<ViewPager> viewPagerClass = ViewPager.class;
//Get the left edge field, since it is private we used getDeclaredField and not getDeclared
Field leftEdge = viewPagerClass.getDeclaredField("mLeftEdge");
leftEdge.setAccessible(true);
//Get the right edge field, since it is private we used getDeclaredField and not getDeclared
Field rightEdge = viewPagerClass.getDeclaredField("mRightEdge");
rightEdge.setAccessible(true);
EdgeEffectForEarlyVersions leftEdgeEffect = new EdgeEffectForEarlyVersions(context);
EdgeEffectForEarlyVersions rightEdgeEffect = new EdgeEffectForEarlyVersions(context);
//Set the mLeftEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect
leftEdge.set(viewPager, leftEdgeEffect);
//Set the mRightEdge memeber of viewPager not to be the default one, but to be "our" edgeEffect
rightEdge.set(viewPager, rightEdgeEffect);
}
catch (Exception ex)
{
Log.e("refelection", ex.getMessage());
}
}
}
Part III
Now all there is left to do, is to call that function after you have the ViewPager Instance and nothing more.
I Hope it will help someone.
wnafee explained the solution well but for the lazy among us, i made an actual working implementation quite some time ago.
https://github.com/inovex/ViewPager3D
And if you just want overscroll take a look here:
https://github.com/inovex/ViewPager3D/issues/1
You have a lot of options, you can show a Toast, display a Dialog, make a TextView or image to appear over your UI, etc. Or because you know the amount of View items in the ViewPager, you could add different View at positions 0 and/or n + 1 with the message and make it bounce to the last View that actually contains your data.
You could implement:
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageSelected(int position) {
//TODO If position is the 0 or n item, add a view at 0 or at n+1 to indicate there is no more pages with data.
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Show a Toast, View or do anything you want when position = your first/last item;
}
public void onPageScrollStateChanged(int state) {
}
});
just to complement #goBeepit dev answer when you create your own edgeffect class and you extend from EdgeEffectCompat some methods requires to be boolean. you can change those methods to boolean type and make then return true in any case, this way everything works fine
You can overload the setUserVisibleHint(boolean) function in your fragments. Pseudo code:
void setUserVisibleHint(boolean isVisibleToUser) {
// If this fragment is becoming visible
if (isVisibleToUser == true) {
// Check if it is the last fragment in the viewpager
if (indexOfThis == getActivity().indexOfLast) {
// Display right limit reached
Toast(..., "No more Frags to right",...)
}
// Check if it is the first fragment in the viewpager
else if (indexOfThis == getActivity().indexOfFirst) {
// Display Left Limit reached
Toast(..., "No more Frags to left",...)
}
}
}
I have not used this function for this purpose, but have used it for other reasons and it does fire appropriately. Hope this helps...
I've implemented a bounce back effect based on Renard's ViewPager3D: https://stackoverflow.com/a/17425468/973379
Usually with ViewPager, one uses a PagerAdapter such as FragmentPagerAdapter or FragmentStatePagerAdapter to flood the ViewPager with contents(your content are going to be views).
Now, when you use a PagerAdapter, you have one method called getCount(), http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getCount%28%29 ,which will give you the size of the content.
Since you now, know the size you can easily display a message with an if control statement.
Try this code : http://developer.android.com/reference/android/support/v4/view/ViewPager.html
Note: I dont think you need a custom ViewPager. You will also need to understand Fragments for ViewPager. Look at samples in ApiDemos. Its a great source.

Categories

Resources