I have created this database enter image description here and want to show the list specifically for the child availability: "Available" item. I have nearly reached to the goal by this code
public class Homeuser extends AppCompatActivity {
SharedPreferences preferences;
SharedPreferences.Editor editor;
ListView lv;
FirebaseListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homeuser);
final Vibrator vibeuser = (Vibrator) Homeuser.this.getSystemService(Context.VIBRATOR_SERVICE);
preferences = PreferenceManager.getDefaultSharedPreferences(this);
editor = preferences.edit();
Query query = FirebaseDatabase.getInstance().getReference().child("food");
lv = findViewById(R.id.list_item);
FirebaseListOptions<food> options = new FirebaseListOptions.Builder<food>()
.setLayout(R.layout.list_items).setLifecycleOwner(Homeuser.this)
.setQuery(query,food.class).build();
adapter = new FirebaseListAdapter(options)
{
#Override
protected void populateView(View v, Object model, int position) {
TextView itemname, itemprice, avail;
itemname = v.findViewById(R.id.itemname);
itemprice = v.findViewById(R.id.itemprice);
avail = v.findViewById(R.id.avail);
food itemFood = (food) model;
if(itemFood.getAvailability().toString().equals("Available")){
itemname.setText(itemFood.getFooditemname().toString());
itemprice.setText(itemFood.getFooditemprice().toString());
avail.setText(itemFood.getAvailability().toString());}
}
};}}
But faces a problem like this:
enter image description here how to get rid of this? Thank you.
If you want to filter Firebase database records, you should use a query along with a whereEqual() call and not an if statement inside your populateView() method. So to solve this, please change the following line of code:
Query query = FirebaseDatabase.getInstance().getReference().child("food");
to
Query query = FirebaseDatabase.getInstance().getReference()
.child("food")
.orderByChild("availability")
.equalTo("Available");
And remove the if statement.
I made a ListView for my chat application. I'm using Firebase but I have a problem:
It shows every data from the server which slows the loading time drastically.
I would like to make a Query which only shows the last 10-30 or 50 element from the list, but I don't know how to develop it and didn't find enough good answer for me in the Query Api Reference. It would be better if I could dynamically adjust the number like every other chat app (Viber, Messenger) if I scroll up.
So here is my display implementation:
private void displayChatMessages() {
listOfMessages = (ListView) findViewById(R.id.list_of_messages);
adapter = new FirebaseListAdapter<ChatMessage>(this, ChatMessage.class,
R.layout.message, FirebaseDatabase.getInstance().getReference()) {
#Override
protected void populateView(View v, ChatMessage model, int position) {
// Get references to the views of message.xml
TextView messageText = (TextView) v.findViewById(R.id.message_text);
TextView messageUser = (TextView) v.findViewById(R.id.message_user);
TextView messageTime = (TextView) v.findViewById(R.id.message_time);
// Set their text
messageText.setText(model.getMessageText());
messageUser.setText(model.getMessageUser());
// Format the date before showing it
messageTime.setText(DateFormat.format("yyyy-MM-dd (HH:mm:ss)",
model.getMessageTime()));
}
};
listOfMessages.setAdapter(adapter);
listOfMessages.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
}
Here is something from Firebase Documentation
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
Query recentPostsQuery = databaseReference.child("posts")
.limitToFirst(100);
https://firebase.google.com/docs/database/android/lists-of-data#filtering_data
I have created my own custom adapter class in my android app and I am calling it from one of my activity. I am adding some elements to the view from the adapter class and I need to access those variables from my activity class.
Now, ideally I would expect it to fill the view and then execute the further code in my activity class, but adapter class is taking some time to populate the view and in the meanwhile further code in my activity class is getting executed where no such elements have been added yet.
How do I handle this situation? I come from a js background. Do we have something like promises in java?
According to the answers I have my changed my code to this:
public class HomeActivity extends Activity {
GridView grid;
String text[] = {"Calendar","Uber","Weather","News","Youtube","Clock","Email","Maps","Twitter","Facebook"};
String list_app_name[] = {"calendar","uber","weather","news","youtube","clock","email","maps","twitter","facebook"};
String id_button[] = {"button_calendar","button_uber","button_weather","button_news","button_youtube","button_clock","button_email","button_maps","button_twitter","button_facebook"};
int image[] = {R.drawable.social_icons1,R.drawable.social_icons2,R.drawable.social_icons3,R.drawable.social_icons4,
R.drawable.social_icons5,R.drawable.social_icons6, R.drawable.social_icons7,R.drawable.social_icons8,
R.drawable.social_icons9,R.drawable.social_icons10};
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_home);
//setting up the adapter for gridView
grid = (GridView)findViewById(R.id.simpleGrid);
ImageAdapter ia = new ImageAdapter(this,image,text,id_button);
grid.setAdapter(ia);
ia.notifyDataSetChanged();
try {
initStateOfApps();
} catch (JSONException e) {
e.printStackTrace();
}
}
public void initStateOfApps() throws JSONException {
Log.d("here","here");
ArrayList<String> list = getEnabledApps();
Log.d("apps",list.toString());
for(int i=0;i<list.size();i++) {
String app_name = list.get(i);
ToggleButton button=null;
if(app_name.equals("calendar")) {
button = (ToggleButton)findViewById(R.id.button_calendar);
button.setChecked(true);
}
}
}
}
So what is happening is that I am creating some toggle buttons that are getting populated in the ImageAdapter class that I wrote.
Once the ImageAdapter is called, I call the notifydatasetchanged() on the adapter in order to update the view.
What I am doing inside the adapter is giving each of the toggle buttons some custom ID I wrote in res/values/ids.xml.
After using setId on each of the toggle buttons, I try using that ID in my activity class but it gives me nullPointerException in the initStateOfApps() where I am trying to change the state of button.
So even after using the notifyDataSetChanged it is still behaving the same.
ImageAdapter.java
public class ImageAdapter extends BaseAdapter {
private Context context;
private final int item_image[];
private final String item_text[];
private final String button_id[];
public ImageAdapter(Context context, int item_image[], String[] item_text,String[] button) {
this.context = context;
this.item_image = item_image;
this.item_text = item_text;
this.button_id = button;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
// get layout from custom_gridview.xml
gridView = inflater.inflate(R.layout.item, null);
// set value into imageview
final ImageView image = (ImageView) gridView.findViewById(R.id.item_image);
image.setImageResource(item_image[position]);
// set value into textview
TextView text = (TextView) gridView.findViewById(R.id.item_text);
text.setText(item_text[position]);
final ToggleButton button_ = (ToggleButton) gridView.findViewById(R.id.item_button);
if(position==0) {
button_.setId(R.id.button_calendar);
image.setId(R.id.image_calendar);
}
button_.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked)
{
if(context.getResources().getResourceEntryName(toggleButton.getId()).equals("button_calendar")) {
if(isChecked) {
try {
setStateOfApp("calendar","true");
} catch (JSONException e) {
e.printStackTrace();
}
Intent intent = new Intent(context, GoogleApp.class);
((Activity) context).startActivityForResult(intent,10);
} else {
try {
setStateOfApp("calendar","false");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
} else {
gridView = (View) convertView;
}
return gridView;
}
}
You are trying to access View which is not a part of Activity's content view. So you can't access that view directly.
button = (ToggleButton)findViewById(R.id.button_calendar); // will return null
This ToggleButton will be null because findViewById will fail to find out ToggleButton in current content view because that view is present in your Adapter not in content view.
And you are getting nullpointerException because you are trying to access property on null view.
button.setChecked(true); // This button is null
In java we have <Future>, but I don't think it's what you're looking for.
The adapter (extending BaseAdaper) behaviour lets you create the adapter and, even in a second moment, change underlying data via getAdapter().setData() or whatever method you choose to add.
From this perspective, the adapter is a "stupid" component acting as A View containers, you should retrieve data elsewhere (CursorAdapter is different).
So, in your Activity, fill the adapter with needed data and, when finished, call adapter.notifyDatasetChanged(). This will inform the adapter that its own data has changed and it must refresh views
Yes, ideally, the population of the adapter should be coming from the outside. The adapter should really just take in a list of data and map that data to the views. For example, some method or task in the Activity could produce a list of data (probably asynchronously...since you mentioned it) that you then pass into the adapter and then you can notifyDataSetChanged() if you need to.
I can't see your code, but if for some reason the data is truly required to be populated from inside the adapter, you could use an event bus and subscribe to it in the Activity. I would recommend going with the first option, but here are some links if you choose to use an event bus:
https://github.com/greenrobot/EventBus
http://square.github.io/otto/
As per my understanding with your question
You are not properly managed the adapter data in your activity.
If any of the data or code interlinked with your adapter data or values
Then you can start those code after you retrieve the values or data and update the view in your activity.
Please note that use Viewholders in adapter to avoid slow populating and scrolling in listviews.
Viewholders will smooth your process.
I personally suggest you that
Please go with Recyclerview and RecyclerViewAdapter.
So many Android developers are using it.
If you have background tasks in adapter you can prefer to use RX Java or EventBus
If you provide the code
It's better for us to suggest exact solution
I have RecyclerView in fragment and i want when user press button below "Add New Row" it will redirect to new fragment till here there is no problem i can achieve it but now i want the details filled in form will show as new row in recyclerview
As you can see in image above user can add row in RecyclerView dynamically and also there is cross top right of every row which delete row from list.
So,What i want to do is
1) How i can add row to the list with form inputs as soon as user press Save Event then show user newly added row with his entered details in form
In short i want to add row dynamically from list with user inputs in form and also delete it from list when user press cross button at top right of row item
I solved this issue by myself what i did to get data back into first fragment from second fragment
First i create interface to send result to fragment_1(Which has recyclerview) from fragment_2(Which has form)
Here is my form code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.ppl_details_form,container,false);
PPL_Title_Spinner= (Spinner) view.findViewById(R.id.PPL_Spinner);
Title= (EditText) view.findViewById(R.id.ppl_title);
Address= (AutoCompleteTextView) view.findViewById(R.id.ppl_address);
Year= (EditText) view.findViewById(R.id.ppl_passing_year);
Description= (EditText) view.findViewById(R.id.ppl_description);
btn1= (Button) view.findViewById(R.id.ppl_map_button);
Save= (Button) view.findViewById(R.id.ppl_save);
Save_PPL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
title=Title.getText().toString();
address= Address.getText().toString();
year=Year.getText().toString();
description=Description.getText().toString();
//PPL Wrapper
PPL_list_wrapper list=new PPL_list_wrapper(title,year,address);
Add_PPL=(PPL_transfer_data_to_list)getActivity();
Add_PPL.addLocation(list);
fragment_1 fragment1=new fragment_1();
FragmentTransaction fragmentTransaction=getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.Navigation_Main_Layout,fragment1);
fragmentTransaction.commit();
}
});
#Override
public void onAttach(Context context) {
super.onAttach(context);
try{
Add_PPL= (PPL_transfer_data_to_list) context;
}
catch (ClassCastException e){
throw new ClassCastException(getActivity().toString()+" Must Implement Interface");
}
}
And then i implement infterface into Parent Activity and then call fragment_1 method from activity like this
#Override
public void addEvent(PPL_list_wrapper PPL_DATA) {
fragment_1 recycler=new fragment_1();
recycler.PPL_eve(PPL_DATA);
}
Then i get data into fragment_1 and have to make arraylist in fragment static cause without static list will lost its reference and data too and it will stop showing data into recyclerview
public void PPL_eve(final PPL_list_wrapper ppl_list_wrapper){
PPL_wrapper=ppl_list_wrapper;
event_details.add(ppl_list_wrapper);//Static ArrayList
adapter=new ppl_Recycler_Adapter(getActivity(),event_details);
adapter.notifyDataSetChanged();
}
I have to make sure that my list is static
static List<PPL_list_wrapper> event_details=new ArrayList<PPL_list_wrapper>();
I am currently creating a basic news aggregator app for Android, I have so far managed to create multiple HorizontalListViews derived from this: http://www.dev-smart.com/archives/34
I am parsing all data from live JSON objects and arrays.
The process goes something like this:
1) Start app
2) Grab a JSON file which lists all feeds to display
3) Parse feed titles and article links, add each to an array
4) Get number of feeds from array and create individual HorizontalListView for each. i.e. "Irish Times".
5) Apply BaseAdapter "mAdapter" to each HorizontalListView during creation.
My baseadapter is responsible for populating my HorizontalListViews by getting each title and thumbnail.
My problem is however that all my feeds seem to contain the same articles and thumbnails. Now I am only new to Android so I'm not 100% sure whats going wrong here. See screenshot below.
Do I need to create a new BaseAdaptor for each HorizontalListview or can I use the same one to populate all my listviews with unique data.
Here's some code to help explain what I mean:
1) OnCreate method to get JSON data, parse it, get number of feeds and create each HorizontalListView
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listviewdemo);
//--------------------JSON PARSE DATA------------------
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
String json = jParser.getJSONFromUrl(sourcesUrl);
//Parse feed titles and article list
getFeeds(json);
//Create Listviews
for(int i = 0; i < feedTitle.size()-1; i++){
//getArticleImage(i);
addHorzListView(i);
articleArrayCount++;//Used to mark feed count for adaptor to know which array position to look at and retrieve data from.
//Each array position i.e. [1] represents a HorizontalListview and its related articles
}
}
2) addHorzListView method, used to create HorizontalListView and apply adaptor
//Method used to dynamically add HorizontalListViews
public void addHorzListView(int count){
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main_layout);
View view = getLayoutInflater().inflate(R.layout.listview, mainLayout,false);
//Set lists header name
TextView header = (TextView) view.findViewById(R.id.header);
header.setText(feedTitle.get(count));
//Create individual listview
HorizontalListView listview = (HorizontalListView) view.findViewById(R.id.listviewReuse);
listview.setAdapter(mAdapter);
//add listview to array list
listviewList.add(listview);
mainLayout.addView(view, count);
}
3) Baseadaptor itself:
private BaseAdapter mAdapter = new BaseAdapter() {
private OnClickListener mOnButtonClicked = new OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(HorizontalListViewDemo.this);
builder.setMessage("hello from " + v);
builder.setPositiveButton("Cool", null);
builder.show();
}
};
#Override
public int getCount() {
return noOfArticles.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
//Each listview is populated with data here
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View retval = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewitem, null);
TextView title = (TextView) retval.findViewById(R.id.title);
title.setText(getArticleTitle(position));
new DownloadImageTask((ImageView) retval.findViewById(R.id.ImageView01)) .execute(getArticleImage(position));
Button button = (Button) retval.findViewById(R.id.clickbutton);
button.setOnClickListener(mOnButtonClicked);
return retval;
}
};
The adapter mAdapter is currently displaying the articles from the last HorizontalListView that calls it.
Currently I am using the same BaseAdaptor for each ListView as I figured it populated the listview as soon as its called but i looks as though a BaseAdaptor can only be called once, I really dont know.
I want to dynamically populate feeds though without having to create a new Adaptor manually for each HorizontalListView.
Any help would be much appreciated.
So...you got the same info in 4 listview, right? In that case you only need oneAdapter populating 4 listview.
An adapter just provide the views which are visible in that moment to the listview (if it is implemented in the right way) so you can reuse the adapter if the info contained is the same.