I was trying to make a app where you can store information into the Firebase Real Time Database. But when I watched a tutorial there was a error whit mine.
public class CreateActivity extends AppCompatActivity {
Button btnTerug, btnGo;
EditText codeIdt, codeItt;
FirebaseDatabase rootNode;
DatabaseReference reference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create);
btnTerug = (Button) findViewById(R.id.btnTerug);
codeIdt = findViewById(R.id.codeId);
codeItt = findViewById(R.id.codeIt);
btnGo = (Button) findViewById(R.id.btnGo);
//Save data in Database
btnGo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View v) {
rootNode = FirebaseDatabase.getInstance();
reference = rootNode.getReference("Bungalows");
//Get all the values
String codeId = codeIdt.getEditText().getText().toString();
String codeIt = codeItt.getEditText().getText().toString();
DataSaver helperClass = new DataSaver(codeId,codeIt);
reference.setValue(helperClass);
}
});
Both the .getEditText() gives a error: Cannot resolve method 'getEditText' in 'EditText'
Does someone know what I am doing wrong?
Try this!
String codeId = codeIdt.getText().toString();
String codeIt = codeItt.getText().toString();
Related
I want to set text on spinner by user input by using DatabaseReference, but I'm lost with all the guides I read on here
Here is my code
public class EditFragment extends Fragment {
TextInputEditText etusername, etname, etage, height, weight, phone;
Spinner gender;
Button confirm;
FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference root = db.getInstance().getReference();
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_edit, container, false);
etusername = view.findViewById(R.id.userName);
etname = view.findViewById(R.id.name);
etage = view.findViewById(R.id.age);
height = view.findViewById(R.id.height);
weight = view.findViewById(R.id.etweight);
phone = view.findViewById(R.id.phone);
confirm = view.findViewById(R.id.confirmBtn);
Spinner dropdown = view.findViewById(R.id.gender);
String[] items = new String[]{"Male", "Female"};
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_dropdown_item, items);
dropdown.setAdapter(adapter);
DatabaseReference dbuser = FirebaseDatabase
.getInstance()
.getReference("User").child(firebaseAuth.getUid());
dbuser.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
User userProfile = snapshot.getValue(User.class);
etusername.setText(userProfile.getUsername());
etname.setText(userProfile.getName());
etage.setText(userProfile.getAge() + "");
phone.setText(userProfile.getPhoneNumber());
weight.setText((int) userProfile.getWeight() + "");
height.setText((int) userProfile.getHeight() + "");
**--> dropdown.setSelection**
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.w("TAG", "Failed to read value.", error.toException());
}
});
confirm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (etusername.getText().toString().isEmpty() || etname.getText().toString().isEmpty() ||
etage.getText().toString().isEmpty() || phone.getText().toString().isEmpty()) {
Toast.makeText(requireContext(), "Please fill in the text fields", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(requireContext(), "Saved successfully", Toast.LENGTH_SHORT).show();
String username = etusername.getText().toString();
String name = etname.getText().toString();
int age = Integer.parseInt(etage.getText().toString());
double high = Double.parseDouble(Objects.requireNonNull(height.getText()).toString());
double wigh = Double.parseDouble(Objects.requireNonNull(weight.getText()).toString());
String nump = phone.getText().toString();
String gender = dropdown.getSelectedItem().toString();
HashMap<String, Object> userMap = new HashMap<>();
userMap.put("username", username);
userMap.put("name", name);
userMap.put("age", age);
userMap.put("height", high);
userMap.put("weight", wigh);
userMap.put("phoneNumber", nump);
userMap.put("gender", gender);
root.child("User").child(Objects.requireNonNull(firebaseAuth.getUid())).updateChildren(userMap);
Navigation.findNavController(view).navigate(R.id.DestInfo);
}
}
});
return view;
}
}
I don't know how to make it work for dropdown to be set from user input, is there anything I can simply do? or do I need to do the for loop? but how do I get the UserProfile.getGender index? I'm sorry I'm kinda new to this android studio, but I'm trying to learn
so I have an application that is as follows:
login page where the user enters his credentials and can access the main app if his credentials are correct. and if he checks the remember me checkbox, his username and password will be saved in shared preferences so that he can directly go to the main app in the second time.
the main app has a tabbed layout with a viewpager. in one of the tabs, which is a fragment, I use a recyclerview to display data, that I get from a database, in rows.
now in each row there is a reply button that will show details corresponding to each row when clicked. the details will be shown in a new fragment.
so the point is that I managed to replace the tab's fragment with the new fragment using this code in the recyclerview's adapter:
public class recyclerviewAdapter : RecyclerView.Adapter
{
// Event handler for item clicks:
public event EventHandler<int> ItemClick;
List <summary_request> summary_Requests=new List<summary_request>();
//Context context;
public readonly stores_fragment context;
public recyclerviewAdapter(stores_fragment context, List<summary_request> sum_req)
{
this.context = context;
summary_Requests = sum_req;
}
public override RecyclerView.ViewHolder
OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.recycler_view_data, parent, false);
recyclerview_viewholder vh = new recyclerview_viewholder(itemView, OnClick);
return vh;
}
public override void
OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
recyclerview_viewholder vh = holder as recyclerview_viewholder;
vh.by_user.Text = summary_Requests[position].By;
vh.warehousename.Text = summary_Requests[position].warehousename;
vh.project.Text = summary_Requests[position].project;
vh.operations_note.Text = summary_Requests[position].destination_Note;
vh.source_Note.Text = summary_Requests[position].source_Note;
vh.stockType.Text = summary_Requests[position].stockType;
vh.requestStatus.Text = summary_Requests[position].requestStatus;
vh.reply.Click += delegate
{
summary_detail_req fragment = new summary_detail_req();
var fm = context.FragmentManager.BeginTransaction();
fm.Replace(Resource.Id.frameLayout1, fragment);
fm.AddToBackStack(null);
fm.Commit();
int nb = context.FragmentManager.BackStackEntryCount;
Toast.MakeText(context.Context, nb.ToString(), ToastLength.Long).Show();
};
}
private void Reply_Click(object sender, EventArgs e)
{
Toast.MakeText(context.Context, "reply" , ToastLength.Long).Show();
}
public override int ItemCount
{
get { return summary_Requests.Count; }
}
// Raise an event when the item-click takes place:
void OnClick(int position)
{
if (ItemClick != null)
ItemClick(this, position);
}
}
but my context.FragmentManager.BackStackEntryCount remain zero! I don't get it. in my main activity, I am using this code for the backpress function:
stores_fragment.recyclerviewAdapter adapter;
public override void OnBackPressed()
{
string userName = pref.GetString("Username", String.Empty);
string password = pref.GetString("Password", String.Empty);
if (userName != String.Empty || password != String.Empty && adapter.context.FragmentManager.BackStackEntryCount == 0)
{
this.FinishAffinity();
}
else
base.OnBackPressed();
}
but i'm not getting what i want. this function is getting me out of the whole app.the first part of the if statement is because without it, when the I press the back button from the main activity it takes me back to the login page and I don't want that.
my question is what should I do to manage my fragments and the backpress function?
thanks in advance.
so the point is that I managed to replace the tab's fragment with the new fragment using this code in the recyclerview's adapter
According to your description, you want to open another fragment from recyclerview Button.click, if yes, please take a look the following code:
on OnBindViewHolder
int selectedindex;
// Fill in the contents of the photo card (invoked by the layout manager):
public override void
OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
selectedindex =position;
PhotoViewHolder vh = holder as PhotoViewHolder;
// Set the ImageView and TextView in this ViewHolder's CardView
// from this position in the photo album:
vh.Image.SetImageResource(mPhotoAlbum[position].PhotoID);
vh.Caption.Text = mPhotoAlbum[position].Caption;
vh.btnreply.Click += Btnreply_Click;
}
To show detailed activity. MainActivity is the current activity for recyclerview.
private void Btnreply_Click(object sender, EventArgs e)
{
Showdetailed(selectedindex);
}
private void Showdetailed(int position)
{
var intent = new Intent();
intent.SetClass(MainActivity.mac, typeof(DetailsActivity));
intent.PutExtra("selectedid", position);
MainActivity.mac.StartActivity(intent);
}
The detailedactivity.cs:
public class DetailsActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
var index = Intent.Extras.GetInt("selectedid", 0);
var details = DetailsFragment.NewInstance(index); // Details
var fragmentTransaction = FragmentManager.BeginTransaction();
fragmentTransaction.Add(Android.Resource.Id.Content, details);
fragmentTransaction.Commit();
}
}
The DetailsFragment.cs:
public class DetailsFragment : Fragment
{
public int ShownPlayId => Arguments.GetInt("selectedid", 0);
public static DetailsFragment NewInstance(int index)
{
var detailsFrag = new DetailsFragment { Arguments = new Bundle() };
detailsFrag.Arguments.PutInt("selectedid", index);
return detailsFrag;
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
// return inflater.Inflate(Resource.Layout.YourFragment, container, false);
if (container == null)
{
// Currently in a layout without a container, so no reason to create our view.
return null;
}
var scroller = new ScrollView(Activity);
var text = new TextView(Activity);
var padding = Convert.ToInt32(TypedValue.ApplyDimension(ComplexUnitType.Dip, 4, Activity.Resources.DisplayMetrics));
text.SetPadding(padding, padding, padding, padding);
text.TextSize = 24;
Photo photo =PhotoAlbum.mBuiltInPhotos[ShownPlayId];
text.Text = photo.Caption;
scroller.AddView(text);
return scroller;
}
}
About implementing fragment, you can take a look:
https://learn.microsoft.com/en-us/samples/xamarin/monodroid-samples/fragmentswalkthrough/
I'm trying to achieve an Instagram style comment section. I have a collection group query /comments and can display comments just fine with RecyclerView.
Inside of the parent FirestoreRecyclerAdapter onBindViewHolder I have this.
DocumentSnapshot snapshot = getSnapshots().getSnapshot(holder.getAdapterPosition());
String commentId = snapshot.getId();
System.out.println("[CommentID: ]" + commentId);
Query rQuery = mFirestore.collectionGroup("comments")
.whereEqualTo("postId", commentId)
.orderBy("timestamp", Query.Direction.DESCENDING)
.limit(50);
FirestoreRecyclerOptions<SubCommentModel> options = new FirestoreRecyclerOptions.Builder<SubCommentModel>()
.setQuery(rQuery, SubCommentModel.class).build();
RecyclerView replyRecycler = holder.reply_recycler;
rAdapter = new FirestoreRecyclerAdapter<SubCommentModel, ReplyTypeViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull ReplyTypeViewHolder holder, int position, #NonNull SubCommentModel model) {
final SimpleDateFormat FORMAT = new SimpleDateFormat(
"MM/dd/yyyy", Locale.US);
((ReplyTypeViewHolder) holder).author_name.setText(model.getAuthor());
((ReplyTypeViewHolder) holder).comment_text.setText(model.getComment());
((ReplyTypeViewHolder) holder).time_stamp.setText(FORMAT.format(model.getTimestamp()));
}
#NonNull
#Override
public ReplyTypeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment_item, parent, false);
return new ReplyTypeViewHolder(view);
}
Outside of this block, I set replyRecycler to the nested adapter; I set up Linear Layout Manager and start listening.
However this does nothing. In fact doing addSnapShotLinstener to cQuery returns nothing. No error and no data.
I have a activity which have two fragments.
Activity receives broadcast events for the two fragments.
One fragment has a image button and text view. When the image button is clicked an event is send to the server and server responds back with live broadcast event.
We receive the response in activity and I need to update the UI of the fragment(the image button needs to be changed with another image)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.single_window_lock, container, false);
updateUI(view);
return view;
}
public void updateUI(View view){
String lockName;
final String lockState;
final boolean state;
final ImageButton singleLockImage = (ImageButton)view.findViewById(R.id.single_lock_image);
final TextView lockNameText = (TextView)view.findViewById(R.id.single_lock_name);
final TextView lockStateText = (TextView)view.findViewById(R.id.single_lock_state);
final ProgressBar progress = (ProgressBar)view.findViewById(R.id.singleLockProgress);
doorLock = LockState.getValue();
lockName = doorLock.getName();
if (doorLock.isLocked()) {
lockState = getActivity().getString(R.string.door_locks_locked);
singleLockImage.setImageResource(R.drawable.doorlocks_single_locked);
state = true;
} else {
lockState = getActivity().getString(R.string.door_locks_unlocked);
singleLockImage.setImageResource(R.drawable.doorlocks_single_unlocked);
state = false;
}
lockNameText.setText(lockName);
lockStateText.setText(lockState);
singleLockImage.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().changeState(state);
}
}
);
}
I thought to call updateUI, which will get the new state from the cache saved after the broadcast event received in Activity, but I am not sure how to pass (view)
Use FragmentActivity instead.
in FragmentActivity :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
// Create an instance of ExampleFragment
TestFragment0 firstFragment = new TestFragment0();
// In case this activity was started with special instructions from an Intent,
// pass the Intent's extras to the fragment as arguments
firstFragment.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).commit();
}
in FragmentActivity for fragments :
TestFragment0 firstFragment0 = new TestFragment0();
firstFragment0.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,firstFragment0).commit();
I'm using the Android Studio provided class for a tabbed activity that uses Action Bar Tabs with ViewPager. Inside this activity, I'm trying to initialize a RecyclerView with data from a Firebase database.
Problem: On the app's first run, the RecyclerView is empty as shown below.
If I close and reopen the application from within the emulator, my RecyclerView gets populated as it should, as shown below.
Any ideas as to why this might be happening? I have a theory but I haven't been able to find a solution. After trying to read the FragmentPagerAdapter page, I got the impression that the fragments must be static (I don't know what the implications of this might be, so if anyone can shed some light on this it would be appreciated). On the app's first run, it initializes the RecyclerView. It then adds the data from the Firebase database but since the RecyclerView has already been initialized it is empty and is never properly updated. I tried calling the notify... methods to no avail.
StudentFragment's onCreateView method:
private View view;
private Context c;
private RecyclerView mRecyclerView;
private LinearLayoutManager manager;
private Firebase mFirebaseRef;
private FirebaseRecyclerAdapter<Student, ViewHolder> firebaseRecyclerAdapter;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_students, container, false);
mFirebaseRef = new Firebase("<your Firebase link here>");
c = getContext();
//Initializes Recycler View and Layout Manager.
mRecyclerView = (RecyclerView) view.findViewById(R.id.studentRecyclerView);
manager = new LinearLayoutManager(c);
mRecyclerView.setHasFixedSize(true);
firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter<Student, ViewHolder>(
Student.class,
R.layout.single_student_recycler,
ViewHolder.class,
mFirebaseRef
) {
#Override
protected void populateViewHolder(ViewHolder viewHolder, Student student, int i) {
viewHolder.vFirst.setText(student.getFirst());
viewHolder.vLast.setText(student.getLast());
viewHolder.vDue.setText(Double.toString(student.getCurrentlyDue()));
viewHolder.vRadio.setButtonTintList(ColorStateList.valueOf(Color.parseColor(student.getColor())));
Log.d(TAG, "populateViewHolder called");
}
};
mRecyclerView.setAdapter(firebaseRecyclerAdapter);
mRecyclerView.setLayoutManager(manager);
return view;
}
ViewHolder:
public static class ViewHolder extends RecyclerView.ViewHolder {
public final TextView vFirst;
public final TextView vLast;
public final TextView vDue;
public final RadioButton vRadio;
public ViewHolder(View itemView) {
super(itemView);
vFirst = (TextView) itemView.findViewById(R.id.recycler_main_text);
vLast = (TextView) itemView.findViewById(R.id.recycler_sub_text);
vRadio = (RadioButton) itemView.findViewById(R.id.recycler_radio_button);
vDue = (TextView) itemView.findViewById(R.id.recycler_due_text);
}
Homescreen's onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homescreen);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
Firebase context is set on another application that starts as soon as the Homescreen activity starts. Any help will be appreciated.
Edit: I was digging through the FirebaseUI GitHub page, which is where the problem most likely lies, and found another user with the exact same problem. It seems that onBindViewHolder isn't called after notifyItemInserted in the FirebaseRecyclerAdapter class. Now to fix it...
In my case this was caused by mRecyclerView.setHasFixedSize(true); If you comment out this line of code the list loads properly. I got my solution from this discussion: https://github.com/firebase/FirebaseUI-Android/issues/204
Let me try, as you say on the question title,
RecyclerView not displaying on application start
so, the
Initializes Recycler View and Layout Manager.
should be declared on the onStart
#Override
public void onStart() {
super.onStart();
mFirebaseRef = new Firebase("<your Firebase link here>");
firebaseRecyclerAdapter = ...
//and so on
Hope it helps!
firebaseRecyclerAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = firebaseRecyclerAdapter.getItemCount();
int lastVisiblePosition =
linearLayoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the
// user is at the bottom of the list, scroll to the bottom
// of the list to show the newly added message.
if (lastVisiblePosition == -1 ||
(positionStart >= (friendlyMessageCount - 1) &&
lastVisiblePosition == (positionStart - 1))) {
linearLayoutManager.scrollToPosition(positionStart);
}
}
});
recyclerListIdeas.setAdapter(firebaseRecyclerAdapter);
** Just add Recyclerview.AdapterDataObserver() . worked for me ! hope it helps :)**
i had the same issue, check the documentation:
https://codelabs.developers.google.com/codelabs/firebase-android/#6
fixed it by adding a data observer:
mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = mFirebaseAdapter.getItemCount();
int lastVisiblePosition =
mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the
// user is at the bottom of the list, scroll to the bottom
// of the list to show the newly added message.
if (lastVisiblePosition == -1 ||
(positionStart >= (friendlyMessageCount - 1) &&
lastVisiblePosition == (positionStart - 1))) {
mMessageRecyclerView.scrollToPosition(positionStart);
}
}
});