Databinding Event listener - java

I am trying to set an event listener to an ImageButton but I keep getting this error.
Error:(48, 36) Could not resolve handler::onSelectPictureClicked as a listener.
Here is what my layout looks like.
<data>
<variable
name="handler"
type="CompleteProfileActivityHandler"/>
</data>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_badge_upload"
android:background="#null"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:contentDescription="#string/select_picture"
android:id="#+id/complete_profile_picture_select"
android:onClick="#{handler::onSelectPictureClicked}"/>
And here's my handler class
public class CompleteProfileActivityHandler{
public void onSelectPictureClicked(View view){
choosePicture();
}
}
Thanks in advance. ;)

So I finally figured out what the problem was.
I did not bind the handler to the view in the Activity.
Here's how I did it:
binding.setHandler(new CompleteProfileActivityHandler());

I think your listenr class must implements View.OnClickListener class
public class CompleteProfileActivityHandler implements View.OnClickListener{
public void onSelectPictureClicked(View view){
choosePicture();
}
}
you have to wrate your code on the callback method of this interface.

Related

Can't cast View.getContext to host Activity

<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="#drawable/window_foreground">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="#dimen/appbar_resting"
android:theme="#style/AppTheme.NoActionBar">
<com.ujjwal.univhub.components.SearchView
android:id="#+id/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/fragment_university_lsit"></include>
</FrameLayout>
app_bar_main.xml
Here searchView is customFrameLayout.I used this xml file in my main activity xml file.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
layout="#layout/floating_action_group"/>
</FrameLayout>
This is activity_main.xml
public class SearchView extends FrameLayout implements AdapterView.OnItemClickListener{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SuggestionAdapter.ViewHolder viewHolder = (SuggestionAdapter.ViewHolder)view.getTag();
University selectedUniversity = viewHolder.getUniversity();
String sendData = FilterBuilder.createCodeFilter(selectedUniversity.getCode()).toJson();
//may occure error here
Log.d("serach by name", "onItemClick: error");
KeyListener listener = new KeyListener((BaseActivity)getContext());//error thrown here.
listener.onClicked(sendData, Properties.LOCALHOST + Properties.UNIVERSITY_CODE);
queryInput.setText(selectedUniversity.getName());
suggestionAdapter.clear();
suggestionAdapter.notifyDataSetChanged();
}
}
In my MainActivity
setContentView(R.layout.activity_main);
java.lang.ClassCastException: android.view.ContextThemeWrapper cannot be cast to com.ujjwal.univhub.BaseActivity
My can't i cast context to the activity hosting the view.
ClassCastException simply means the object isn't of the type (or can't safely behave as the type) you are trying to cast into.
This might help.
If you create the view programatically providing an explicit context (your BaseActivity) using constructor new SearchView(yourBaseActivityContext), this exception should not be thrown. However, from xml, I'm not sure if the LayoutInflater uses your activity context or a more generic context for constructing the view.
Edit: (in response to op's comment)
i need it to post the data in UI through the handler of baseActivity. KeyListener will have to get access to BaseActivity instance. If i
have to make keylistener independent of activity then its will require
a complete turn over of the implementation.
In your BaseActivity, make an interface:
public interface KeyClickListener { void clicked(SomeUiData data) }
add a method to your SearchView class to register a listener (e.g. your BaseActivity) which can be notified
private BaseActivity.KeyClickListener mListener;
public void setKeyClickListener(BaseActivity.KeyClickListener listener) {
mListener = listener;
}
in your BaseActivity's onCreate() (so that listener is registered before any user clicks can be performed):
mSearchView = findViewById... ;// get your SearchView instance
mSearchView.setKeyclickListener(new KeyClickListener() {
void clicked(SomeUiData newUiInfo) {
// update your UI using newUiInfo here
// use any handler accessible in your BaseActivity
}
});
So, effectively, now you have a listener which is declared in your BaseActivity which can perform any UI update actions without KeyListener needing BaseActivity instance. Pass mListener to your KeyListener and in your original KeyListener.onClicked() method, you could invoke any methods you declared in KeyClickListener with the click/ui data which can update the UI (because it is declared in the activity).

AppCompatImageView cannot be cast to my class

I have problem with my android java code, I hope you can help me with this.
I have my class with ImageView parent... some like this:
public abstract class BaseStatus extends ImageView
{
public BaseStatus(Context context){
super(context);
}
}
public class BluetoothStatus extends BaseStatus
{
public BluetoothStatus(Context context){
super(context);
}
}
and I want to get the component as ImageView from the XML, you know...
BluetoothStatus btStatus;
btStatus = (BluetoothStatus) findViewById(R.id.bt_status); // ERROR
XML:
<ImageView
android:layout_width="85dp"
android:layout_height="wrap_content"
android:id="#+id/bt_status"
android:src="#drawable/bluetooth"
android:layout_alignTop="#+id/button3"
android:layout_alignEnd="#+id/lb_laser" />
and i got this message:
Caused by: java.lang.ClassCastException: android.support.v7.widget.AppCompatImageView cannot be cast to net.antiradary.radarhunter.activity.status.BluetoothStatus
Why i can not cast ImageView into BluetoothStatus?
Thank you for you answers!
it was enough to do jus this...
<net.antiradary.radarhunter.activity.status.BluetoothStatus
android:layout_width="85dp"
android:layout_height="wrap_content"
android:id="#+id/iv_bluetooth"
android:src="#drawable/bluetooth"
android:layout_alignTop="#+id/button3"
android:layout_alignEnd="#+id/lb_laser" />
and in my class make constructor like this
class BluetoothStatus extends ImageView
{
public BluetoothStatus(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
I know i am late to the party, but just in case some is banging his head for same problem, here is one possible solution that worked for me when i was trying to add zoom functionality in my pager adapter images.
Info: this is not the exact answer, but a possible solution for those who are facing the same problem. I am posting this because i didn't fount this solution approach anywhere in stackOverflow
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/head_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/head_image" />
</RelativeLayout>
In the above code, just Replace <ImageView with <com.yourPackage.TouchImageView.
TouchImageView (or any other class) is a custom class (you need to make)which should extend android.support.v7.widget.AppCompatImageView

setText() on a textView coming from a subClass in Android

First I'm a beginner in Android development !
In my app, I include a library that help me to create card UI.
In this library, you have a basic layout where there is a Title, a description and a thumbnails but you can create and inflate a custom layout for having a better filled card.
What I want to do is to change the text of a TextView coming from the sub Class, which is linked to the sub Layout. But everytime I try to invoke the setText method from the MainActivity, I get a NullPointerexception.
There is my sub Class:
import it.gmariotti.cardslib.library.internal.Card;
import it.gmariotti.cardslib.library.internal.Card.OnCardClickListener;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
public class CustomCardAccueil extends Card{
public TextView TitreExtensionAccueil;
public TextView DateSortieAccueil;
public TextView NombreCarteAccueil;
public TextView DescriptionExtensionAccueil;
public TextView RareteCarteAccueil;
public TextView DetailExtensionAccueil;
public CustomCardAccueil(Context context) {
this(context, R.layout.accueil_mycard_inner_content);
}
/**
*
* #param context
* #param innerLayout
*/
public CustomCardAccueil(Context context, int innerLayout) {
super(context, innerLayout);
init();
}
/**
* Init
*/
private void init(){
//No Header
//Set a OnClickListener listener
setOnClickListener(new OnCardClickListener() {
#Override
public void onClick(Card card, View view) {
Toast.makeText(getContext(), "Click Listener card=", Toast.LENGTH_LONG).show();
}
});
}
#Override
public void setupInnerViewElements(ViewGroup parent, View view) {
TitreExtensionAccueil = (TextView) parent.findViewById(R.id.TitreExtensionAccueil);
}
}
My Layout where there is the TextView that I want to change:
<?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" >
<TextView
android:id="#+id/TitreExtensionAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textStyle="bold"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/DateSortieAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/TitreExtensionAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/NombreCarteAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/DateSortieAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/DescriptionExtensionAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/NombreCarteAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/RareteCarteAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/DescriptionExtensionAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/DetailExtensionAccueil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/RareteCarteAccueil"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
And there is how I try to change the content of TextView in my MainActivity, in the OnCreate:
CustomCardAccueil.TitreExtensionAccueil.setText("Test");
There is also the error I get in the logcat of the crash:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText.setText(java.lang.CharSequence)' on a null object reference
I don't understand the error because the object is initiated (correct me if I'm wrong).
Also if I try to change the text from the sub class (CustomCardAccueil), it's a success, but I need to do it through my MainActivity.
Any help is appreciated, thanks in advance !
You need to initialize the class with something like:
CustomCardAccueil myCard = new CustomCardAccueil(mContext, R.mylayout);
The context you can get from your activity class using something like MyActivity.this or getApplicationContext(). Then you can use methods such as the class' setText:
myCard.setText("blah")
Your TitreExtensionAccueil is said to be null when you are trying to set the text.
You may want to point out where are CustomCardAccueil.TitreExtensionAccueil.setText("Test"); is called for better respond to your question.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText.setText(java.lang.CharSequence)' on a null object reference
shows that you invoked setText() on a null object, so did you initialize CustomCardAccueil.TitreExtensionAccueil and how?
your problem is or you are not using the proper instance for the class CustomCardAccueil, as you declared and initialized the TextView through it, So, even you have to make an instance from the class or to make the TextView declared as static variable, but make sure you run the method called setupInnerViewElements() before trying to set the TextView value.
UPDATE:
to get the current window view through some layout:
View global_view = getWindow().getDecorView(); // use that in the MainActivity to get the view
then, pass that view to your method setupInnerViewElements() and simply create the view with it not with ViewGroup:
in your MainActivity:
CustomCardAccueil mCard = new CustomCardAccueil(getApplicationContext(), R.layout.accueil_mycard_inner_content);
mCard.setupInnerViewElements(parent, global_view);
in your setupInnerViewElements() method:
#Override
public void setupInnerViewElements(ViewGroup parent, View view) {
TitreExtensionAccueil = (TextView) view.findViewById(R.id.TitreExtensionAccueil);
}
I've found the answer by looking at the card library and his setTitle Library (I don't know why I've not thinked to this sooner !)
In my CustomCardAccueil class, I've created a String as this:
protected static String titreExtension;
Here is the getter and setter methods:
public String getTitreExtension() {
return titreExtension;
}
public static void setTitreExtension(String titre) {
titreExtension = titre;
}
Again in CustomCardAccueil, in setupInnerViewElements method, I've put this:
TitreExtensionAccueil = (TextView) view.findViewById(R.id.TitreExtensionAccueil);
TitreExtensionAccueil.setText(titreExtension);
And in my MainActivity I simply call my setter with:
CustomCardAccueil.setTitreExtension("test du setTitreExtension");
Simply as this !

Why is this static field null?

on android.
my activity is like this.
public class MainActivity extends Activity {
static TextView textview;
static int aaa = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
setContentView(R.layout.activity_main);
textview = (TextView)findViewById(R.id.textView6);
//other method,startservice()and so on.
and there is BroadcastReceiver to receive a flag from service.
public static class Receiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intents) {
intents.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
textview.setText("set")//throw null point
Log.d("aaa","aaa is" + aaa);
like this, in onReceiver, textview is null.
as test, int aaa is'nt null.
why textview is null?
EDIT
Texttiew xml is
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/adview"
android:layout_alignParentLeft="true"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
And method in Activity using same textview.settext isnt null.
Thanks.
EDIT2
I can know i should save this variable.
So, whats the best way to save VIEW variable?
SharedPreferences seem not able to save VIEW variable.
This thread indicates that having static fields might be a problem.
In general, android kills your app.. and on return static variables may not be set.
static variable null when returning to the app
This is likely that you are not referencing the correct textview element. Double check your IDs in your layout file.

Why Fragment cannot be public static class?

I came across such problem: I wanted to have some Fragment as public static member of my Activity class.
But when I put such Fragment to layout file I receive such exception:
Caused by: android.support.v4.app.Fragment$InstantiationException:
Unable to instantiate fragment com.tst.MainActivity.InnerFragment:
make sure class name exists, is public,
and has an empty constructor that is public
...
My code looks like this:
package com.tst;
public final class MainActivity extends SherlockFragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public static class InnerFragment extends SherlockFragment {
public InnerFragment() {
super();
}
...
}
}
Layout file looks like this:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<fragment
android:id="#+id/inner_fragment"
android:name="com.tst.MainActivity.InnerFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
Now my question is why such code throws this Exception? As Android should be able to instanitate InnerFragment as it is public static. What is more I used to use public static Fragments and they worked, but on that time I added them programmatically in code not in xml definition.
Regards,
Michal
Change
android:name="com.tst.MainActivity.InnerFragment"
to
android:class="com.tst.MainActivity$InnerFragment"

Categories