Android Studio Button OnClick Causing Failure? - android

I'm working on an application for android in Android Studio and I'm attempting to make an on-click listener like so:
Button menu_button = (Button)findViewById(R.id.menu_button);
menu_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
However, when I start genymotion it tells me that the app has stopped working. If I remove this code:
menu_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
The application runs fine. I'm very confused and was hoping maybe someone could point something out I'm not understanding.
Here's the full code of the main activity I'm working on, and I should note that the button is inside a ViewPager.
public class MainActivity extends FragmentActivity {
private ViewPager m_BackgroundViewPager;
private ViewPager m_PanelViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature((int) Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
m_BackgroundViewPager = (ViewPager)(findViewById(R.id.mainViewPager));
m_PanelViewPager = (ViewPager)(findViewById(R.id.bottomViewPager));
m_BackgroundViewPager.setAdapter
(new BackgroundPagerAdapter(getSupportFragmentManager(), this));
m_PanelViewPager.setAdapter
(new PanelPagerAdapter(getSupportFragmentManager(), this));
Button menu_button = (Button)findViewById(R.id.menu_button);
menu_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}
LogCat Results:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at eqlogic.annswingsandthings.MainActivity.onCreate(MainActivity.java:37)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#998822">
<Button
android:layout_width="75dp"
android:layout_height="75dp"
android:id="#+id/menu_button"
android:text="Menu"
android:textSize="12dp" />
</FrameLayout>

Create a global variable for your Button as follows :
Button menu_button;
Then in your onCreate() you add this line :
menu_button = (Button)findViewById(R.id.menu_button);
And now whenever you want to make a setOnClickListener() you can do it like you were doing :
menu_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Your click stuff
}
});
EDIT
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
Make sure that in your activity_main.xml your button has this :
android:id="#+id/menu_button"

Problem is that the button is inside the view pager.
So in order to display the button either remove it out of the view pager or add it to the xml of the fragment which forms part of the view pager and inflate it in that fragment.

Related

Implementing a WebView within a CardView using a RecyclerView [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am using a WebView within a CardView with Recyclerview.
I implemented them correctly, but the problem is that when I run application it crashes and shows a nullpointer exception,
Log crash report:
java.lang.RuntimeException: Unable to start activity ComponentInfo{andro.petrochemical/andro.petrochemical.webViewNews}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.webkit.WebView.setWebViewClient(android.webkit.WebViewClient)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.webkit.WebView.setWebViewClient(android.webkit.WebViewClient)' on a null object reference
at andro.petrochemical.webViewNews.onCreate(webViewNews.java:33)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6077) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
WebView CardView xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/webView_news"/>
</LinearLayout>
</android.support.v7.widget.CardView>
RecyclerView xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:id="#+id/resycleWeb"/>
</LinearLayout>
WebView java class file:
public class webViewNews extends AppCompatActivity {
private WebView webviewthis;
private RecyclerView webVieRes;
private DatabaseReference mdataRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview_page);
webVieRes = (RecyclerView) findViewById(R.id.resycleWeb);
mdataRef = FirebaseDatabase.getInstance().getReference().child("weber");
webviewthis = (WebView)findViewById(R.id.webView_news);
webviewthis.setWebViewClient(new WebViewClient());
webviewthis.getSettings().setJavaScriptEnabled(true);
webviewthis.getSettings().setLoadsImagesAutomatically(true);
}
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerAdapter<post2web,post2webViewHolder> firebaseRecyclerAdapte = new FirebaseRecyclerAdapter<post2web,post2webViewHolder>(
post2web.class,
R.layout.web_card,
post2webViewHolder.class,
mdataRef
) {
#Override
protected void populateViewHolder(post2webViewHolder viewHolder, post2web model, int position) {
viewHolder.setWebViewPost(model.getWebViewPost());
}
};
webVieRes.setAdapter(firebaseRecyclerAdapte);
}
public static class post2webViewHolder extends RecyclerView.ViewHolder {
View mVie;
public post2webViewHolder(View itemView) {
super(itemView);
mVie = itemView;
}
public void setWebViewPost(String webViewPost) {
WebView post_web = (WebView) mVie.findViewById(R.id.webView_news);
post_web.loadUrl(webViewPost);
}
}
}
Remove webview initialization from onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview_page);
webVieRes = (RecyclerView) findViewById(R.id.resycleWeb);
mdataRef = FirebaseDatabase.getInstance().getReference().child("weber");
}
And update in post2webViewHolder
public void setWebViewPost(String webViewPost) {
WebView post_web = (WebView) mVie.findViewById(R.id.webView_news);
post_web.loadUrl(webViewPost);
post_web.setWebViewClient(new WebViewClient());
post_web.getSettings().setJavaScriptEnabled(true);
post_web.getSettings().setLoadsImagesAutomatically(true);
}
You need to only find the WebView from the post2webViewHolder
It's not part of the Activity, therefore it's null
Remove webviewthis

Android buttons null pointer [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am trying to add an onClickListener to a button, but log cat outputs an error
Here is the log cat
FATAL EXCEPTION: main
Process: com.pk.a_loner, PID: 10539
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pk.a_loner/com.pk.a_loner.main.gui.Connect}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2814)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2879)
at android.app.ActivityThread.access$900(ActivityThread.java:182)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1475)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6141)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.pk.a_loner.main.gui.Connect.init(Connect.java:20)
at com.pk.a_loner.main.gui.Connect.onCreate(Connect.java:53)
at android.app.Activity.performCreate(Activity.java:6374)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2767)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2879) 
at android.app.ActivityThread.access$900(ActivityThread.java:182) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1475) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:6141) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 
The code below, should be fine?
package com.pk.a_loner.main.gui;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.pk.a_loner.R;
import com.pk.a_loner.main.networking.Broadcast;
import com.pk.a_loner.main.networking.Listen;
public class Connect extends AppCompatActivity {
private Button button_toggleBroadcast;
private Button button_listen;
private void init() {
this.button_toggleBroadcast = (Button) (findViewById(R.id.button));
this.button_toggleBroadcast.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
if (!Broadcast.isInBroadcast()) {
if (!Broadcast.isHasInit()) {
Broadcast.init();
}
Broadcast.broadcast();
} else {
Broadcast.halt();
}
}
});
this.button_listen = (Button) (findViewById(R.id.button2));
this.button_listen.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
if (!Listen.isInScan()) {
if (!Listen.isHasInit()) {
Listen.init();
}
Listen.scan();
} else {
Listen.halt();
}
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("hello world", "this is a hello");
this.init();
setContentView(R.layout.activity_launcher);
}
}
and here is the xml
<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".main.gui.Connect">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toggle broadcast"
android:id="#+id/button" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Listen 10 secs"
android:id="#+id/button2" />
</LinearLayout>
</RelativeLayout>
I checked the code, I did initialize the buttons before I add the listener, shouldn't be null? buttons also declared in xml.
The app currently crashes on startup.
Any help appreciated, many thanks.
Use this in your onCreate() instead:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("hello world", "this is a hello");
setContentView(R.layout.activity_launcher);
this.init();
}
You need to initialise your views AFTER your layout has been inflated by setContentView()
call setContentView(R.layout.activity_launcher); before init();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("hello world", "this is a hello");
setContentView(R.layout.activity_launcher);
this.init();
}

Null TextView object in a fragment

I'm working on dynamically setting a text of TextView in a fragment called 'ChallengeFragment' by creating a method that sets the text. Then, I call the method in FragmentActivity class to update the TextView. However, I am getting error that TextView object is null when the method is called. I am not sure why TextView is null.
Here's the logcat message:
16:36:02.437 4072-4072/eie.android.crunch E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: eie.android.crunch, PID: 4072
java.lang.RuntimeException: Unable to start activity ComponentInfo{eie.android.crunch/eie.android.crunch.ChallengePage}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at eie.android.crunch.ChallengeFragment.setNameText(ChallengeFragment.java:76)
at eie.android.crunch.ChallengePage.onCreate(ChallengePage.java:50)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Here is the Fragment class (ChallengeFragment.java):
public class ChallengeFragment extends Fragment {
private Activity mActivity;
private TextView nameText;
private Handler handler =new Handler();
public ChallengeFragment() {
}
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater lf = getActivity().getLayoutInflater();
View v = lf.inflate(R.layout.fragment_challenge, null);
nameText = (TextView) v.findViewById(R.id.user_name_text_view);
....
return v;
}
public void setNameText(String s) {
nameText.setText(s);
}
public TextView getNameText() {
return nameText;
}
}
And this is the code for FragmentActivity that updates the text of TextView (ChallengePage.java):
public class ChallengePage extends FragmentActivity {
private FriendChallengeFragment initialFriendHabit;
private ChallengeFragment friendHabit;
private ChallengeFragment myHabit;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_challenge);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
myHabit = new ChallengeFragment();
initialFriendHabit = new FriendChallengeFragment();
myHabit.onAttach(ChallengePage.this);
initialFriendHabit.onAttach(ChallengePage.this);
fragmentTransaction
.replace(R.id.my_habit, myHabit ,"fragment_top")
.replace(R.id.friend_habit, initialFriendHabit, "fragment_bottom")
.commit();
Intent intent = getIntent();
String challengedUsername = intent.getStringExtra("username");
if(challengedUsername != null) {
friendHabit = new ChallengeFragment();
friendHabit.onAttach(ChallengePage.this);
fragmentTransaction.replace(R.id.friend_habit, friendHabit, "fragment_bottom");
friendHabit.setNameText(challengedUsername);
}
}
}
And this is the layout file that contains the fragment (fragment_challenge.xml):
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:id="#+id/user_name_text_view"
android:layout_gravity="center_horizontal"
android:text="User Name"
android:textSize="30dp"
android:layout_marginTop="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:id="#+id/habit_name_text"
android:layout_gravity="center_horizontal"
android:text="Habit Name"
android:textSize="40dp"
android:layout_marginTop="20dp"/>
<ProgressBar
android:layout_height="wrap_content"
android:layout_width="312dp"
style="#android:style/Widget.ProgressBar.Horizontal"
android:id="#+id/progressBar"
android:layout_marginTop="50dp"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
I've looked at other stackoverflow questions relating to this but could not find answers.
The problem is your fragment's setNameText() method is called before onCreateView() has run, so your TextView has not been initialized yet. You have to wait until later to set the name text.
If you always have the name text when you are creating and adding the fragment, then it's better to pass that as an argument to the fragment and have it set the text of the TextView at the appropriate time. Something like this:
public class ChallengeFragment extends Fragment {
public static ChallengeFragment newInstance(String name) {
ChallengeFragment fragment = new ChallengeFragment();
Bundle args = new Bundle();
args.putString("username", name);
fragment.setArguments(args);
return fragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
Bundle args = getArguments();
if (args != null) {
String name = args.getString("username");
nameText.setText(name);
}
}
// everything else
}
A few things to note:
Do not create a constructor. Fragments need to have a default (no argument) constructor so that Android can instantiate them. This newInstance pattern is typically regarded as the best practice.
Use onActivityCreated because at that time you know the Activity is created and that the fragment's view hierarchy has been created.
Fragment arguments persist across configuration changes, so you shouldn't need to do anything special for that.
Also, you should not be calling onAttach() yourself, that's a lifecycle method that the OS calls on your fragment.

List View Fragment Won't Display

I am trying to display a list in my main activity using a ListFragment. The list is populated by my custom ArrayAdapter that uses a custom object. I am having trouble getting this list to show in the app. When I debug, it doesn't show any errors but the app immediately crashes.
Here is my fragment
Edit: I have tried several responses and have narrowed down the issue to the momentObjectListView.setAdapter(momentObjectAdapter) in the ListViewFragment. I cannot find a reason why the momentObjectAdapter would be null so it must be momentObjectListView however I cannot find where the issue stems. Any help would be much appreciated. My activity_main.xml, fragment, main activity, and adapter code are all included.
public class ListViewFragment extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Activity myAct = getActivity();
View view = inflater.inflate(R.layout.activity_main, container, false);
ListView momentObjectListView = (ListView)view.findViewById(R.id.list_item);
//ListView momentObjectListView = getListView();
MomentObjectAdapter momentObjectAdapter = new MomentObjectAdapter(myAct, R.layout.moment_object_list_item);
//momentObjectListView.setAdapter(momentObjectAdapter);
List<MomentObject> myMoments = getMoments();
for(final MomentObject entry : myMoments) {
momentObjectAdapter.add(entry);
}
//ListViewFragment.this.setListAdapter(momentObjectAdapter);
momentObjectListView.setAdapter(momentObjectAdapter);
return view;
}
private List<MomentObject> getMoments() {
// Let's setup some test data.
// Normally this would come from some asynchronous fetch into a data source
// such as a sqlite database, or an HTTP request
final List<MomentObject> entries = new ArrayList<MomentObject>();
for(int i = 1; i < 50; i++) {
entries.add(
new MomentObject(
"Test Entry " + i,
"Anonymous Author",
new GregorianCalendar(2011, 11, i).getTime(),
R.drawable.photoicon
)
);
}
return entries;
}
}
And here is my activity_main.xml
<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" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity"
android:background="#ffffffff">
<fragment android:name="com.malatras.moment2.ListViewFragment"
android:id="#+id/list"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Please let me know if there is anything I need to provide to solve this.
LogCat:
e02-24 18:54:29.119 2325-2325/com.malatras.moment2 I/art﹕ Not late-enabling -Xcheck:jni (already on)
02-24 18:54:29.191 2325-2325/com.malatras.moment2 D/AndroidRuntime﹕ Shutting down VM
02-24 18:54:29.191 2325-2325/com.malatras.moment2 E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.malatras.moment2, PID: 2325
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.malatras.moment2/com.malatras.moment2.MainActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:377)
at android.app.Activity.setContentView(Activity.java:2144)
at com.malatras.moment2.MainActivity.onCreate(MainActivity.java:11)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34)
at android.app.Fragment.performCreateView(Fragment.java:2053)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:870)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1045)
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1147)
at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2116)
at android.app.Activity.onCreateView(Activity.java:5282)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
            at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:377)
            at android.app.Activity.setContentView(Activity.java:2144)
            at com.malatras.moment2.MainActivity.onCreate(MainActivity.java:11)
            at android.app.Activity.performCreate(Activity.java:5933)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
MainActivity:
public class MainActivity extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MomentObjectAdapter:
public final class MomentObjectAdapter extends ArrayAdapter<MomentObject> {
private final int momentObjectLayoutResource;
public MomentObjectAdapter(final Context context, final int momentObjectLayoutResource) {
super(context, 0);
this.momentObjectLayoutResource = momentObjectLayoutResource;
}
#Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
// We need to get the best view (re-used if possible) and then
// retrieve its corresponding ViewHolder, which optimizes lookup efficiency
final View view = getWorkingView(convertView);
final ViewHolder viewHolder = getViewHolder(view);
final MomentObject entry = getItem(position);
// Setting the title view is straightforward
viewHolder.titleView.setText(entry.getTitle());
// Setting the subTitle view requires a tiny bit of formatting
final String formattedSubTitle = String.format("By %s on %s",
entry.getAuthor(),
DateFormat.getDateInstance(DateFormat.SHORT).format(entry.getPostDate())
);
viewHolder.subTitleView.setText(formattedSubTitle);
// Setting image view is also simple
viewHolder.imageView.setImageResource(entry.getIcon());
return view;
}
private View getWorkingView(final View convertView) {
// The workingView is basically just the convertView re-used if possible
// or inflated new if not possible
View workingView = null;
if(null == convertView) {
final Context context = getContext();
final LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
workingView = inflater.inflate(momentObjectLayoutResource, null);
} else {
workingView = convertView;
}
return workingView;
}
private ViewHolder getViewHolder(final View workingView) {
// The viewHolder allows us to avoid re-looking up view references
// Since views are recycled, these references will never change
final Object tag = workingView.getTag();
ViewHolder viewHolder = null;
if(null == tag || !(tag instanceof ViewHolder)) {
viewHolder = new ViewHolder();
viewHolder.titleView = (TextView) workingView.findViewById(R.id.moment_object_title);
viewHolder.subTitleView = (TextView) workingView.findViewById(R.id.moment_object_subtitle);
viewHolder.imageView = (ImageView) workingView.findViewById(R.id.moment_object_icon);
workingView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) tag;
}
return viewHolder;
}
/**
* ViewHolder allows us to avoid re-looking up view references
* Since views are recycled, these references will never change
*/
private static class ViewHolder {
public TextView titleView;
public TextView subTitleView;
public ImageView imageView;
}
}
moment_object_list_item:
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for individual news entries in a list -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Icon shown next to the title/subtitle -->
<ImageView
android:id="#+id/moment_object_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:padding="3dp" />
<!-- Title of the news entry -->
<TextView
android:id="#+id/moment_object_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/moment_object_icon"
android:layout_alignTop="#id/moment_object_icon"
android:layout_margin="5dp"
android:textSize="14sp"
android:textStyle="bold" />
<!-- Subtitle contains author and date -->
<TextView
android:id="#+id/moment_object_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/moment_object_title"
android:layout_below="#id/moment_object_title"
android:textSize="12sp" />
</RelativeLayout>
This code I don't like and not compatible with your method getMoments is:
for(final MomentObject entry : getMoments()) {
momentObjectAdapter.add(entry);
}
For now try this for a quick sample fix:
List<MomentObject> myMoments = getMoments();
for(final MomentObject entry : myMoments) {
The reason is getMoments() in the for loop is evaluated dynamically. I think so even though you declared it with final.
In the log,
Attempt to invoke virtual method 'void
android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a
null object reference
I believe object momentObjectListView is null. I could not find the UI in fragment_list_view.xml. It is however in activity_main.xml. Sample code :
View view = inflater.inflate(R.layout.activity_main, container, false);
ListView momentObjectListView = (ListView)view.findViewById(R.id.list);
Sample layout element for a ListFragment in activity_main:
<fragment android:name="com.malatras.moment2.ListViewFragment"
android:id="#+id/list"
...>
A good webpage for explaining layouts is required for understanding the basics # Layouts .
Change in your XML file this line : android:id="#+id/list"
to:
android:id="#id/android:list
and in ListViewFragment change this : ListView momentObjectListView =(ListView)view.findViewById(R.id.list);
to this:
ListView momentObjectListView = (ListView)view.findViewById(android.R.id.list);
In your Logcat file, it says
android.view.InflateException: Binary XML file line #9: Error
inflating class fragment
This means an xml file is not proper. Also deeper in the log,
The code MainActivity.onCreate(MainActivity.java:11)
...
Caused by: java.lang.NullPointerException: Attempt to invoke virtual
method 'void
android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a
null object reference at
com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34)
...
ListViewFragment.onCreateView(ListViewFragment.java:34)
Need to load file ListViewFragment.java too. In order to save time, perhaps post more files.
Another possible good code change is to modify ListViewFragment definition from:
public class ListViewFragment extends ListFragment {
to:
public class ListViewFragment extends Fragment implements AbsListView.OnItemClickListener {
The OnItemClickListener is optional.
The reason I say this is that MainActivity already hosts ListView object through ListActivity. Another reason, Android Studio wizard generates the "to" suggested code. And it sounds good to me.
Another way is to remove ListActivity from MainActivity to just Activity, with the same reason.
All these suggestions may be considered to be code style however.

PopupMenu inside Adapter getView() not working

I'm using a custom adapter and adding this code on getView() method:
final ImageView popupMenu = (ImageView) v.findViewById(R.id.popupMenu);
popupMenu.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
popupMenu.setImageResource(R.drawable.ic_popup_menu_selected);
PopupMenu popup = new PopupMenu(context, view);
popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu());
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
#Override
public void onDismiss(PopupMenu pm) {
popupMenu.setImageResource(R.drawable.ic_popup_menu);
}
});
popup.show();
}
});
But I get this error:
java.lang.RuntimeException: Failed to resolve attribute at index 6
The same code works onListItemClick() but it doesn't make sense to be there because it needs to be clicked once to setup and click again to trigger the PopupMenu.
Edit: Logcat
11-02 17:58:51.276 1996-1996/com.android.example E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.android.example, PID: 1996
java.lang.RuntimeException: Failed to resolve attribute at index 6
at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:603)
at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:6423)
at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:6591)
at android.widget.FrameLayout$LayoutParams.<init>(FrameLayout.java:735)
at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:679)
at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:62)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.support.v7.internal.view.menu.MenuPopupHelper$MenuAdapter.getView(MenuPopupHelper.java:363)
at android.support.v7.internal.view.menu.MenuPopupHelper.measureContentWidth(MenuPopupHelper.java:212)
at android.support.v7.internal.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:146)
at android.support.v7.internal.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:118)
at android.support.v7.widget.PopupMenu.show(PopupMenu.java:168)
at com.android.example.GetAdapter$listAdapter$1.onClick(GetAdapter.java:81)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
With the following import I always had the error:
import android.support.v7.widget.PopupMenu;
It works fine with the following import:
import android.widget.PopupMenu;
Full answer: stackoverflow.com/a/27826670/4548500
I solve it this way:
Add this on adapter getView():
ImageView popupMenu = (ImageView) v.findViewById(R.id.popupMenu);
popupMenu.setTag(getItem(position));
popupMenu.setOnClickListener(MyFragment.popupMenuListener);
And this on MyFragment:
implements OnClickListener
popupMenuListener = this;
#Override
public void onClick(final View view) {
view.post(new Runnable() {
#Override
public void run() {
showPopupMenu(view);
}
});
}
This issue is related to missing theme attributes.
Make sure that your app theme extends Theme.AppCompat.
<style name="AppTheme" parent="#style/Theme.AppCompat" />

Categories

Resources