Why is the function setVm(user) error?
This is MainActivity.java:
package com.example.heriprastio.databindingandroid;
import android.databinding.DataBindingUtil;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.example.heriprastio.databindingandroid.databinding.ActivityMainBinding;
import com.example.heriprastio.databindingandroid.model.User;
public class MainActivity extends AppCompatActivity {
private User user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
user = new User();
user.setName("Heri");
user.setEmail("heriprastio#gmail.com");
binding.setVm(user);
}
}
This is my model class:
package com.example.heriprastio.databindingandroid.model;
public class User {
String name;
String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
And this is my "activity_main" file layout:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<data>
<variable
name="vm"
type="com.example.heriprastio.databindingandroid.MainActivity"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{vm.text}"
android:textSize="16sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{vm.email}"/>
</LinearLayout>
</layout>
In the function setVm(user) cannot be applied, why is this? Can you explain, about this error?
And I have to solve this error or replace it with what?
You've declared your activity as variable type in the layout, but in the activity code you're passing an User instance as layout variable. To make it working, you have to make next changes:
In your layout file change
type="com.example.heriprastio.databindingandroid.MainActivity"
to
type="com.example.heriprastio.databindingandroid.model.User"
Moreover, I see that you're using "#{vm.text}" variable in the layout, even though you don't have such method or field in the User class. I suppose you wanted to use the user's name instead. So you must change it to "#{vm.name}"
Related
I am new to android and trying out the example of data binding as below. The text is not displayed, rather an empty box is displayed.
build.gradle :
databinding {
enabled = true
}
HelloWorld.java :
package com.example.android.databinding;
public class HelloWorld {
public String getText() {
return "My Name is ";
}
}
MainActivity.java :
package com.example.android.databinding;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.os.Bundle;
import com.example.android.databinding.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
HelloWorld mViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
activityMainBinding.setViewModel(mViewModel);
activityMainBinding.executePendingBindings();
}
}
activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.example.android.databinding.HelloWorld" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{viewModel.text}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Output :
You need to instantiate the HelloWorld class before sending it via DataBinding
mViewModel = new HelloWorld();
activityMainBinding.setViewModel(mViewModel);
Also, you don't have a filed text in HelloWorld class, so android:text="#{viewModel.text}" won't get compiled.
So you need to add it, and set its value, I am using constructor in that:
public class HelloWorld {
String text;
public HelloWorld() {
text = getText();
}
public String getText() {
return "My Name is ";
}
}
TachesFragment.java
package com.example.johnwalls.projet;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.ArrayList;
/**
* A simple {#link Fragment} subclass.
*/
public class TachesFragment extends Fragment {
private DB base;
private ListView sp ;
public TachesFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_taches, container, false);
TextView text2 = view.findViewById(R.id.ta);//Find textview Id
TextView t1 = view.findViewById(R.id.t1);
TextView de1= view.findViewById(R.id.de1);
TextView em1= view.findViewById(R.id.em1);
String getArgument = getArguments().getString("main");
text2.setText(getArgument);
base=new DB(getActivity());
text2.setText(getArgument);
sp=(ListView) view.findViewById(R.id.ta);
ArrayList<Mission> empList=base.MissionList();
ArrayAdapter<String> adapter=new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,android.R.id.text1,empList);
sp.setAdapter(adapter);
return view;
}
}
fragment_taches
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:gravity="bottom"
android:orientation="vertical"
android:background="#drawable/ee63"
tools:context="com.example.johnwalls.projet.TachesFragment">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="100dp"
android:layout_marginBottom="15dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:id="#+id/ta"
/>
</android.support.v4.widget.DrawerLayout>
simple_list_item_1
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/t1"
android:textSize="20dp"
android:text=""
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/de1"
android:textSize="10dp"
android:text=""
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/em1"
android:textSize="10dp"
android:text=""
/>
</LinearLayout>
What are you trying to achieve what are you expecting to get out What did you get out (include error messages) What else have you tried? What do you think is causing it? Why do you need to make a new question for it? Why is your problem different to other, similar questions on here?
I believe that your issue is that you are telling the ArrayAdapter to expect an Array of String objects (ArrayAdapter<String>) but you are providing an array of Mission objects as per ArrayList<Mission> emplist=base.MissionList();.
i.e. you have
ArrayList<Mission> empList=base.MissionList();
ArrayAdapter<String> adapter=new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,android.R.id.text1,empList);
Instead I think you need :-
ArrayList<Mission> empList=base.MissionList(); //<<<< NOT CHANGED
ArrayAdapter<Mission> adapter=new ArrayAdapter<>(getActivity(),android.R.layout.simple_list_item_1,android.R.id.text1,empList);
Note the mission's toString method will be used to provide the data for the list, if you haven't overridden the toString method the result may be not what you expect. e.g.
com.example.johnwalls.projet.Mission#546789
Note it will be like the above certainly the numeric will be different.
Why it comes out like this is explained by :-
How do I print my Java object without getting “SomeType#2f92e0f4”?
In which case you should create a toString method to return an appropriate string.
As an example (not to be used as it is) here's a TaskData class with an overridden toString method :-
public class TaskData {
private long id;
private String type, name, owner, expiration;
public TaskData(long id, String type, String name, String owner, String expiration) {
this.id = id;
this.type = type;
this.name = name;
this.owner = owner;
this.expiration = expiration;
}
//<<<< Oreridden toString Method Starts here >>>>
public String toString() {
return " Typ: " + type + " Name: " + name + " Owner: " + owner + " Until: " + expiration;
}
//<<<< End >>>>
public long getId(){return id;}
public String getType() {return this.type;}
public String getName() {return this.name;}
public String getOwner() {return this.owner;}
public String getExpiration() {return this.expiration;}
}
The overridden toString method returns a string that combines the type name and owner and expiration. e.g.
Type: Test Name: Fred Owner: Bert Until: 31/12/2018
LoveData beanClass = arrayList.get(position);
Log.e("DisplayPhotolistAdapter","beanClass:"+beanClass);
tv_date.setText(beanClass.getLOVE_DATE());
tv_total_percent.setText(beanClass.getPrcentage()+"%");
tv_hername.setText(beanClass.getHername());
tv_hisname.setText(beanClass.getHisname());
tv_Actvity.setText(beanClass.getActvity()+":");
I created the simple application App, the user enters his name in EditText and click on "Enter here" button and store his name in String variable that is instance variable then will move to another activity "activity_welcome" and will display his name in TextView
My problem:
when I create an object from Main Class to get the variable name in welcome Class when running this app, the name do not store in TextView that means that
the object main refers to null
My question:
why object main refer to null?
When I make the variable name as a static variable the app will display the name in TextView that mean that object main store the value of name variable
Note:
Main class
package code.app;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class Main extends AppCompatActivity {
EditText editText ;
String name ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText=findViewById(R.id.et) ;
}
public void Go (View v){
name=editText.getText().toString() ;
Intent intent= new Intent(this,Welcome.class);
startActivity(intent);
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ba"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffff"
>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="50dp"
android:hint="Enter Your Name"
android:textColorHint="#000"
android:id="#+id/tv1"
android:textColor="#000"
android:background="#ffffff"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="50dp"
android:text="Enter Here"
android:background="#645353"
android:onClick="Go"/>
</LinearLayout>
Welcome Class
package code.app;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;
public class Welcome extends AppCompatActivity {
TextView textView ;
#Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
textView =findViewById(R.id.tv);
Main main =new Main () ;
Toast.makeText(this,main.name, Toast.LENGTH_SHORT).show(); // this Toast donot display any thing
textView.setText(main.name);
}
}
activity_welcome
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tv"
android:layout_margin="50dp"
/>
</LinearLayout>
Just keep it simple and put string inside your intent when you go to another activity, obtain intent, and then string from the intent.
public void Go (View v){
name=editText.getText().toString() ;
Intent intent= new Intent(this,Welcome.class);
intent.putExtra("name", name);
startActivity(intent);
}
Obtain it in your welcome activity like this.
#Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
textView =findViewById(R.id.tv);
Intent intent = getIntent();
if(intent!=null) {
String name = intent.getStringExtra("name");
Toast.makeText(this, name, Toast.LENGTH_SHORT).show();
textView.setText(name);
}
}
I am working in MVVM design pattern.
I want to use dataBinding or RXJava in order to notify the View when the model has changed.
dataBinding can do it inside xml.
but i want to notify the Activity on a change in the model and do something more complicated.
let's assume i want my TextView to change color when text in not empty.
can you help me to do it via dataBinding or RXJava ?
here is my code:
xml
<?xml version="1.0" encoding="utf-8"?>
<data>
<variable
name="viewModel"
type="edi.com.mydatabindingsimple.MyViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="#={viewModel.txt}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#={viewModel.txt}" />
</LinearLayout>
Activity
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import edi.com.mydatabindingsimple.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
MyViewModel viewModel = new MyViewModel();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setViewModel(viewModel);
}
}
viewModel
import android.databinding.BaseObservable;
import android.databinding.Bindable;
public class MyViewModel extends BaseObservable{
private String txt;
#Bindable
public String getTxt() {
return txt;
}
public void setTxt(String txt) {
this.txt = txt;
notifyPropertyChanged(edi.com.mydatabindingsimple.BR.txt);
}
}
What you can do is create a callback mechanism to trigger a method in your Activity. This will still notify the ViewModel first, but the effect will be the same.
You can create a new interface (or add it inside the ViewModel)
public interface ViewModelCallback{
void ActionCallback();
}
In your Activity:
public class MainActivity extends AppCompatActivity implements ViewModelCallback
In your ViewModel
private ArrayList<ViewModelCallback> callbacks = new ArrayList<>();
public void notifyCallbacks(){
for(ViewModelCallback c : callbacks){
if(c != null){
c.ActionCallback
}
}
}
public void addCallback(ViewModelCallback c){
callbacks.add(c);
}
Call notifyCallback after your NotifyPropertyChanged().
And don't forget to add your activity as a callback in onCreate
viewModel.addCallback(this)
You should also remove it in onDestroy.
I am working on Android project, which will allow users to find nearest petrol pump's name, address, and most importantly their prices. I have a ListView, which I want to populate through Firebase list adapter because I am using Firebase for my project. Now after writing code I am getting nothing from Firebase -- it's just blank screen on Android phone (no error showing in Android Studio).
After writing setContentView(lview); in the end of the onCreate() method , it is giving me error now and the activity crashes. Finally I got the error from firebase : com.firebase.client.FirebaseException: Failed to bounce to type
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import com.firebase.client.Firebase;
import com.firebase.ui.FirebaseListAdapter;
public class testbezinpriser extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_testbezinpriser);
ListView lview = new ListView(this);
Firebase.setAndroidContext(this);
Firebase ref = new Firebase("https://xxxxx.firebaseio.com");
FirebaseListAdapter<Benzin> Adapter = new FirebaseListAdapter<Benzin>(this, Benzin.class, R.layout.listepriser, ref) {
#Override
protected void populateView(View v, Benzin s, int i) {
((TextView)v.findViewById(R.id.navnView)).setText(s.getName());
((TextView)v.findViewById(R.id.addressView)).setText(s.getAddress());
((TextView)v.findViewById(R.id.prisView)).setText(s.getPrice()));
}
};
lview.setAdapter(Adapter);
setContentView(lview);
}
}
And Benzin class
public class Benzin {
String Address;
String Name ;
String Price;
public Benzin(){
}
public Benzin (String Name , String Address , String Price){
this.Name = Name;
this.Address = Address;
this.Price = Price;
}
public String getAddress(){
return Address;
}
public String getName(){
return Name;
}
public String getPrice(){
return Price;
}
}
XML Layout for listepriser
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="80dp"
android:layout_height="50dp"
android:id="#+id/logoView"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_marginTop="20dp"
android:src="#drawable/shell"
android:contentDescription="tankstation_billed" />
<TextView
android:layout_width="70dp"
android:layout_height="25dp"
android:id="#+id/navnView"
android:layout_alignTop="#+id/logoView"
android:layout_toEndOf="#+id/logoView"
android:layout_marginStart="10dp"
android:textStyle="bold|italic"
android:textSize="15sp"
android:textColor="#000000"
android:text="SHELL"
android:layout_marginTop="5dp"
android:textIsSelectable="false" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Måløvhovedgade 38 , Måløv"
android:id="#+id/addressView"
android:layout_alignBottom="#+id/logoView"
android:layout_alignStart="#+id/navnView"
android:layout_marginBottom="3dp"
android:textSize="12sp"
android:textColor="#000000" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="10.99"
android:id="#+id/prisView"
android:layout_alignTop="#+id/navnView"
android:layout_alignParentEnd="true"
android:layout_marginRight="10dp"
android:textColor="#000000"
android:typeface="serif" />
Database view
If you look at the full stack trace of the Failed to bounce to type exception, it will tell you what is wrong.
But in this case it seems likely that your problem is caused by the fact that the property names in your JSON start with an uppercase letter. This is likely to work:
public class Benzin {
public String Address;
public String Name ;
public String Price;
}
Try changing your Firebase reference. It doesn't look like it pointing to the right location. Based on the link you posted to your data structure it looks like you are trying to list objects stored in your /detail location. If that true try using a ref like this:
Firebase ref = new Firebase("https://xxxxx.firebaseio.com/detail");
Just a guess here.
Your getPrice() method returns a string. I think you need a getter that has the same return type as the property you are getting. You can keep the String one, but it must be in addition to a method with the signature...
public Double getPrice();
The reason I think this is because firebase is complaining that it is unable to figure what property of your object a certain field matches to. This could be because you are supposed to provide getters for each property, and Firebase may not like that price is a Double but your getter turns it into a string. Here is a link to a detailed post about how this all works by Frank. Why do I get "Failed to bounce to type" when I turn JSON from Firebase into Java objects?
I haven't used Firebase before, but shouldn't the ListView be added to the layout (or be retrieved from it)?
Something like
setContentView(R.layout.activity_testbezinpriser);
ListView lview = (ListView)findViewById(R.id.station_list);
In the activity_testbezinpriser.xml, there should be a ListView, like
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:id="#+id/station_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>