I'm new to Android programming, and still teaching myself to code.
Currently I'm teaching myself about GridViews and still coding that project with tutorials so I have nothing to show right now, but the basic idea is the following...
If I have images of groceries in GridView in the first activity and when you click an image you will be able to open a new activity with a larger image and you could input the number how many you things you need, like 5 apples or whatever.
All of that is more or less clear to me how to do.
But how would I send the number and image to a new (third) activity with a ListView that would list all the items you need to buy at the grocery store? How would I be able to fill the list only with items after you enter the number on the previous activity with the large picture and click an "OK" or "Add" button or whatever and not list absolutely everything?
Thanks!
It's difficult at first, but you can use an SQLiteDatabase to store the data.
It's not a quick solution for you, but definitely worth learning about if you're serious to learn android. Here's a link to the official stuff:
https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
I personally used this tutorial:
http://www.androidwarriors.com/2016/02/android-sqlite-database-tutorial-sqlite.html?m=1
Sharing some data between multiple activities or fragments is a very common situation. One way around it is implementing a Singleton Pattern.
In your case you can design some kind of data structure for your purpose and manage it inside shared singleton class. For example something like this:
public class ShoppingListManager {
private static ShoppingListManager instance = new ShoppingListManager();
private List<ShoppingItem> shoppingList;
public static ShoppingListManager getInstance() {
return instance;
}
public List<ShoppingItem> getShoppingList() {
return shoppingList;
}
public void addShoppingItem(ShoppingItem item) {
this.shoppingList.add(item);
}
...
// Make the constructor private so that this class cannot be instantiated
private ShoppingListManager(){
shoppingList = new ArrayList<String>();
}
}
Then you can access your data anywhere in your code and manage shared data in any way you'd like.
ShoppingListManager.getInstance().getShoppingList();
// You can add items in any activity
ShoppingListManager.getInstance().addShoppingItem(item);
One point to remember never store context in singleton classes as it will lead to memory leaks.
Related
Screen 1: GridView
Screen 2: Detail Page
Task Achieve:
1) Load all the videos in gridview from the server.
2) User clicks at any position of gridview item.
3) Open and play the particular video in detail screen.
4) On vertical scroll play next or previous videos.
Current Implementation:
GridFragment {
ArrayList<VideoPostModel> videoPostList;
RecyclerView gridView;
onnItemClick() {
Intent intent = new Intent(this, DetailActivity.class);
intent.putExtra("data", videoPostList);
intent.putExtra("click_index", clickedIndex);
intent.putExtra("pagination_index", paginationIndex);
startActivity(intent);
}
}
DetailActivity {
VerticlaViewPager vertiCalViewPager;
ArrayList<VideoPostModel> videoPostList;
onCreate() {
videoPostList = getIntent().getParcelableArrayListExtra("data");
clickedIndex = getIntent().getIntExtra("clickindex", 0);
paginationIndex = getIntent().getIntExtra("pagination_index", 0);
VideoFragmentStatePagerAdapter viewPagerAdapter = new VideoFragmentStatePagerAdapter(videoPostList);
vertiCalViewPager.setAdapter(viewPagerAdapter);
}
}
Problem:
If videoPostList has more data(approx 100+ objects of VideoPostModel) while passing data from fragment to activity then app crashes, as there is a limitation of sending data with intent(https://stackoverflow.com/a/37054839/3598052).
Hacky Alternatives:
1) Static arraylist
2) Arraylist in Application class
Looking for the OPTIMAL and EFFICIENT solution to achieve above functionality.
Any suggestion, reference link or code in the direction of achieving this would be highly appreciated, and thanks in advance.
Update 1:
Another solution I found is passing data with enum, but as per comments I'm not sure about it's performance. Refrence: https://stackoverflow.com/a/14706456/3598052
I think you can write in an activity or use Arraylist in the application as you mentioned. Or it could be a library that recently appeared in the Android Jetpack. It is similar in nature to the Arraylist in application.
ViewModel objects that make it easier to manage and store data.
It lets you access data at different activities or fragments in an application. You try it and hope it will be useful to you
You have several options. I'll put my opinion here.
Static list
Enum
Singleton class with list
LiveData
Most easy would be making static list at activity or application level. Just make sure you are freeing up List memory after use by making it NULL.
Another solution I found is passing data with enum, but as per
comments I'm not sure about it's performance
There would be sure some differences in each of above approaches. But that would not be measurable difference, because each approach put List in memory, use it and then free up.
Looking for the OPTIMAL and EFFICIENT solution to achieve above
functionality.
Make static List, and make it NULL after use. will be most efficient and easy way.
You can make List NULL in onDestroy() of your Fragment.
You can use LiveData but I think it would be not a good idea to add LiveData library just for one use in app. Also you need to understand it first. So you can go with static list.
in Activity
showFragment();
ApplicationClass.list = myList;
In Fragment
onViewCreated(){
...
setAdapter(ApplicationClass.list);
...
}
onDestroy(){
ApplicationClass.list = null;
}
Important
It is never a good idea to pull all data at once from server. Please do pagination, which you app needs most, because there can be thousands of users online at one time.
So by that approach you will pass only few items to Fragment. then you will do pagination in Fragment.
This approach needs time to change flow a bit. But is most robust way in your case.
Edit
If you are already using pagination and still getting large data at one time, that's again an issue. Because pagination is used to escape these memory issues.
You can do 2 things as solution.
1. Ask for limited data at once, say 50-60 items per request.
2. You can map and remove unnecessary fields from your list when passing in intent.
I would prefer the first one.
I know I'm late but this will help some future visitor.
Add Pagination & transfer data with arraylist & clicked position to detail activity using intent & after, set the current position of clicked position.
like viewpager.setCurrentPosition(clickedPosition);
I'm managing my UI list with RealmRecyclerViewAdapter. I'd like to add a "pending" item to the collection that will display immediately while simultaneously posting the new item to the server. In case of failure, I will remove it from the display. Similar to a chat feature; I display the chat when they hit send, and if for some reason the post fails I can remove it and alert the user.
The problem is that with a regular RecyclerView adapter, I can just add one item to the end of the collection without an id, and remove it as needed. But since RealmRecyclerViewAdapter uses managed RealmResults, I can't add a new item without an id.
Can someone suggest a way to handle the situation I'm describing with RealmRecyclerViewAdapter?
Without knowing what your data model looks like. It is hard to give concrete advice, but it sounds like all your have ID's, so something like this should work:
1) It must be possible to generate ID's offline. The standard solution for that is GUIDs: https://en.wikipedia.org/wiki/Universally_unique_identifier
2) Have a boolean on your model class: "syncedWithServer" or something similar. Then you can render all items not yet synced as "pending".
public class ChatEntry extends RealmObject {
#PrimaryKey
private String id = UUID.randomUUID().toString();
private String entry;
private boolean syncedWithServer;
}
I am new to Android programming and have a basic question.
I have created a ListActivity where each row in its ListView has a TextView and a RatingBar. I am able to display values in the TextView and RatingBar by reading them from a pre-populated database; I am doing this via a custom CursorAdapter and it's bindView() method, i.e.
public class MyCursorAdapter extends CursorAdapter {
...
public void bindView(View view, Context context, final Cursor cursor) {
TextView name = (TextView)view.findViewById(R.id.name);
name.setText(cursor.getString(cursor.getColumnIndex(MyDbAdapter.KEY_NAME)));
RatingBar rating = (RatingBar)view.findViewById(R.id.life_bar_rating);
rating.setRating(cursor.getFloat(cursor.getColumnIndex(MyDbAdapter.KEY_RATING_VALUE)));
}
...
}
Now, my problem is that in my ListActivity I want the user to be able to click a "Save" button so that all changes are saved to the database in one go?. How would I iterate through the adapter to get the row ID and rating values so they can be saved (or is there another better way of doing this?).
The reason why I want to do a save in one go is because I thought it would be bad practice to update the database every time the user makes a change to a single rating (even though this is easier) as this causes more wear and tear on flash memory. I may be wrong about this, but I thought that there are a limited number of reads and writes with flash memory.
Remember the Adapter's backing array? The one you used to initialize it? save that ;)
or if that doesn't work...
for(int i = 0; i < listView.getAdapter().getCount(); i++)
SaveThing(listView.getAdapter().getItem(i));
if you need SQLite examples of saving... tomorrow.
edit for same of keeping comments clean:
as far as that object thing goes - you're free to cast it to anything that's in the listview. the data type, not view type.
so for example, an arrayAdapter that works with strings still returns Objects. but you will most certainly cast them to Strings because you know that's what you put in. it's awkward but thats how it is.
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!
Everything I've read about Intents talks about using them to push data, or to start one Activity from another Activity. I want to pull data from an Activity that's already running.
The Tab Layout tutorial at http://developer.android.com/resources/tutorials/views/hello-tabwidget.html illustrates what I want to do. (My app is doing some engineering calculations instead, but the tutorial code provides a good analogy to my app.) The tutorial creates an app with three tabs, and each tab hosts a separate activity.
To expand on the example in the tutorial, suppose I select an artist in the Artists tab/activity. I want to be able to select the Albums tab/activity and have it display all the albums featuring that artist.
It seems to me that I need to use an Intent to do this. All of the tutorials I've found assume that I would create a "See albums" Button in the Artists tab/activity, and that pressing the Button would execute an Intent that starts the Albums activity and passes artistName.
I DO NOT want to create that Button. Real estate on the Artists layout is precious, and I have a perfectly good Albums tab, AND the HelloTabWidget activity already contains an intent to create the Albums tab.
Besides, a user will want to skip back and forth between Album and Artist in order to change artist selections, and the tabs are a perfectly good way to do this. There's no need to complicate the UI with another button.
So how can I have the Albums activity PULL artistName from the Artists activity when the Albums tab is selected (or the Albums layout is displayed), rather than have the Artists activity START Albums and PUSH the artistName?
Equivalents I can think of from other programming worlds:
Global variables. Discouraged in Android devt, right? And if they do exist, what are they called?
A getter, like artistName = Artists.getArtistName(); . I get the feeling that it's not that easy.
Writing to, and reading from, a file - that is, mass storage or non-volatile memory. I don't need the artistName value to be permanent. It will be reset to null every time the user launches the application.
So how is it done in the Android world? Do I use an Intent - and if so, how?
Global variables were the right answer.
I thought Java discouraged their use, but a couple of links that appeared in the "Related" links on the right margin of this window mentioned them directly. One was "Android: How to declare global variables?" and the other was "how to pass value betweeen two tab in android". Both pointed to the Application Class as the place to define global variables and methods. Armed with this new knowledge, I found an article called "Android Application Class" on the Xoriant blog that expanded on the StackOverflow answers.
It's best to review those three links first. I need to add some tips to what those authors have said.
Your Application class has to be in its own separate file. (That might be a "duh" to some people, but not to everybody.) Here's a good framework for an example called Something.java:
public class Something extends Application {
// Put application wide (global) variables here
// Constants are final, so they don't have to be private
// But other variables should be declared private;
// use getters/setters to access them
public final boolean FEET = false;
public final boolean METERS = true;
private boolean units = FEET;
#Override
public void onCreate() {
super.onCreate();
// Put any application wide (global) initialization here
}
// Put application wide (global) methods here
public boolean getUnits() {
return units;
}
public void setUnits(boolean whichOne) {
units = whichOne;
}
}
I'm using Eclipse with the ADT plug-in, in Windows XP. Eclipse doesn't always behave properly if you edit XML code directly, so it's best to open AndroidManifest.xml, then select the Application tab and enter your application name in the Name field. You don't need to put a dot or period in front of the name. Just type in the name of your class, like "Globals" or "MyApplication" or whatever. (Note that this is the default application in your Manifest. You don't have to create a separate <application></application> tag.
This step may not be necessary on an actual Android device, but it was necessary for the emulator: you need to use the getApplicationContext() command in every onCreate() and every method that will be accessing the global variables and methods. I tried to put it outside of onCreate() with the rest of my activity wide variables, and it didn't work. Putting it inside every method seems wasteful, but both the emulator and the Android device work fine with it that way. Here's a sample showing how I used it:
public void fooBar() {
// Access to global variables and methods
final Something s = (Something)getApplicationContext();
// ...
// This next line demonstrates both a global method and a global variable
if (s.getUnits() == s.FEET) {
// do something with feet
} else {
// do something with meters instead
}
// ...
}
Those were the only hiccups I encountered. The three references that I have listed, taken together, are otherwise pretty complete.