I'm admittedly quite new to Android development and Java in general, having some problems with something I've seen a ton of other people search for as well, but the other solutions don't seem to be doing it for me. I had this exact code working in another file, copied it to a different program (switching from NavigationDrawer to NavigationView) and now the Fragment gives me a NullPointerException when it tries to access the TextView.
As near as I can tell I've defined the view before trying to call findViewById. I'm absolutely certain that the problem is in the method show_life1_total() with the line
TextView life1_total = (TextView) view.findViewById(R.id.life1_total);
but I can't figure out what's wrong with that line because it worked perfectly in a different file. Any help would be most appreciated.
Alternately, if there's some other way I'm supposed to be handling buttons and views in fragments, please enlighten me. They were really easy in activities, but the NavigationView forces me to use fragments, and setting up onClickListeners for every single button I intend to use in a fragment looks like it's going to be a gigantic amount of what should be unnecessary work. Maybe I'm missing something obvious.
Here's my Fragment
package com.android4dev.navigationview;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
/**
* Created by Admin on 04-06-2015.
*/
public class GameFragment extends Fragment implements View.OnClickListener{
public static Integer nlife1Total=20;
public static Integer nlife2Total=20;
View view;
Button life1_minus;
Button life1_plus;
Button life2_minus;
Button life2_plus;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_life_counter,container,false);
life1_minus = (Button) view.findViewById(R.id.life1_minus);
life1_minus.setOnClickListener(this);
life1_plus = (Button) view.findViewById(R.id.life1_plus);
life1_plus.setOnClickListener(this);
life2_minus = (Button) view.findViewById(R.id.life2_minus);
life2_minus.setOnClickListener(this);
life2_plus = (Button) view.findViewById(R.id.life2_plus);
life2_plus.setOnClickListener(this);
show_life1_total();
show_life2_total();
return view;
}
public void startNewGame()
{
nlife1Total=20;
nlife2Total=20;
//show_life1_total();
//show_life2_total();
}
public void show_life1_total() {
TextView life1_total = (TextView) view.findViewById(R.id.life1_total);
String display_life1_total = String.valueOf(nlife1Total);
life1_total.setText(display_life1_total);
}
public void show_life2_total() {
TextView life2_total = (TextView) view.findViewById(R.id.life2_total);
String display_life2_total = String.valueOf(nlife2Total);
life2_total.setText(display_life2_total);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.life1_minus:
nlife1Total--;
show_life1_total();
break;
case R.id.life1_plus:
nlife1Total++;
show_life1_total();
break;
case R.id.life2_minus:
nlife2Total--;
show_life2_total();
break;
case R.id.life2_plus:
nlife2Total++;
show_life2_total();
break;
}
}
}
The relevant view from the xml file (this is in fragment_life_counter.xml)
<TextView
android:id="#+id/life1_total"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textSize="140sp"
android:text="#string/life1_total"
android:fontFamily="sans-serif-thin"
android:textColor="#color/life_color"
android:background="#drawable/backdrop_ubr_grixis" />
Along with the logcat
08-27 22:17:46.103 18943-18943/com.android4dev.navigationview E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.android4dev.navigationview, PID: 18943
java.lang.NullPointerException
at com.android4dev.navigationview.GameFragment.show_life1_total(GameFragment.java:69)
at com.android4dev.navigationview.GameFragment.onCreateView(GameFragment.java:54)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1016)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1197)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1562)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:483)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
You have declared a View in the method that will act as a local varibale and it will be destroyed. Make it a global or you have already declared a global View varibale initailize it.
Follow this-
Instead of--
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_life_counter,container,false);
remove the View because you have already declared it on top of the class.
make it like this--
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_life_counter,container,false);
remember you are trying to access a view object in the show_life1_total() method which is not initialized.
I hope this would help you.
Related
I use four tabs in my android application. An image button is in one tab activity and when I click that button I need to go to another activity which is not a tab activity. I tried a lot to do this, but once I click on the tab my app has stopped work. Please if someone could help me to solve this issue. I really appreciate your help.
This is FirstFragment.java file. I use image button in this activity and after click that button need to go to another activity.
package com.example.user.application001.fragmentspkg;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import com.example.user.application001.Invoice;
import com.example.user.application001.R;
public class FirstFragment extends Fragment {
public FirstFragment(){}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_second, container, false);
ImageButton fabImageButton = (ImageButton) view.findViewById(R.id.fab_image_button);
fabImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), Users.class);
startActivity(intent);
}
});
return view;
}
}
This is the XML file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="#+id/fab_image_button"
android:layout_width="#dimen/fab_button_diameter"
android:layout_height="#dimen/fab_button_diameter"
android:layout_marginBottom="20dp"
android:layout_marginEnd="36dp"
android:layout_marginRight="36dp"
android:background="#drawable/fab_shape"
android:src="#drawable/plusbtn"
android:tint="#android:color/white"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
you are using layout of fragment_second in fragment_first change it
use this
View view = inflater.inflate(R.layout.fragment_first, container, false);
instead of this
View view = inflater.inflate(R.layout.fragment_second, container, false);
In my application, I have multiple instances of the same fragment, Activity_Fragment, displayed in a LinearLayout. In each fragment, there is an activity_text textview and an edit_button. When the button is pressed in a fragment, it should change the text of the textview in the same fragment. However, when multiple instances of the fragment are added, any edit_button pressed in any fragment will only change the activity_text textview in the first fragment added to the LinearLayout. This is because all fragments are identical, and their child views share the same id's. Each fragment should act independently of one other; any edit_button pressed in a fragment should only affect that fragment.
Is it possible to have the findViewById() method limited to the scope of an individual fragment so that one fragment won't be affected by an event in another fragment, or will I have to somehow change the id of each view in a fragment upon creation?
Here is the Activity Fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="wrap_content"
android:id="#+id/activity_fragment">
<CheckBox
android:id="#+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/activity_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="Edit Activity"
android:textSize="18sp"
app:layout_constraintBaseline_toBaselineOf="#+id/checkbox"
app:layout_constraintLeft_toRightOf="#+id/checkbox"
app:layout_constraintRight_toLeftOf="#+id/edit_button"/>
<Button
android:id="#+id/edit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:onClick="editActivity"
android:text="Edit Activity"
app:layout_constraintBaseline_toBaselineOf="#+id/checkbox"
app:layout_constraintRight_toRightOf="parent"/>
Here is my MainActivity.java with the ActivityFragment class. The onClick method for the edit_button is at the very bottom:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public static class ActivityFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.activity_fragment, container,
false);
}
}
public void addActivity(View view) {
ActivityFragment fragment1 = new ActivityFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragment1).commit();
}
//This is the editButton method
public void editActivity(View view) {
TextView activityText = (TextView) findViewById(R.id.activity_text);
activityText.setText("success");
}
}
Your problem can be solved by limiting the scope that findViewById() scans. If you want to look within a particular fragment, you'll probably want to call myFragment.getView().findViewById() (rather than just using findViewById() from your activity).
So how can you do this? Well, it's not easy with the way you have things set up. Since you're using the android:onClick attribute to set your click listener, you have to handle things from inside the activity.
So don't use android:onClick.
Instead, inside your Fragment's onCreateView() method, write something like this:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.your_fragment, container, false);
Button button = (Button) root.findViewById(R.id.edit_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView activityText = (TextView) getView().findViewById(R.id.activity_text);
activityText.setText("success");
}
});
return root;
}
you can use view.findViewById(R.id.activity_text) instead of the method from the activity.
I want to call a new activity when a list item is clicked from the drawer. I searched over the internet and what I got was to call the fragment of that activity. So, I wanted to know how to make a fragment of an activity.
P.S.- Sorry, if this question is silly. I'm still a noob.
A Fragment represents a behavior or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. Here the full explanation from android official developer guide.
Also on android developer guide you can find the code to properly create and use a fragment.
Create a fragment class:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
public class ExampleFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_view, container, false);
}
}
Then you have to add the fragment to the activity layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.example.android.fragments.HeadlinesFragment"
android:id="#+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.android.fragments.ExampleFragment"
android:id="#+id/example_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
Finally you can add the layout to your activity:
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.item_from_exampleLayout);
}
}
I took those examples from the android developer guide that i put above.
Anyway if i have understood your question this code should work:
list.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
Intent intent = new Intent(ThisClass.this, ClassToCall.class);
startActivity(intent);
}
});
This will start a new activity when a list item is clicked using an intent, but it doesn't need fragments.
I am using Google Place API to find nearest places. I am displaying map and list on two tabs. I have made two fragments. In one i am showing map and in second one i am using list. I have used an editext box on actionbar. When i am running my app it is crashing and giving nullpointer exception at setListAdapter.
It is my ListFragment file
import android.support.v4.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.aquib.android.place.Place;
import com.aquib.android.place.PlaceAdapter;
import com.aquib.android.place.R;
import java.util.List;
/**
* Created by dell on 2/9/2015.
*/
public class ListItemFragment extends ListFragment{
private PlaceAdapter adapter;
List<Place> placeList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, null);
TextView emptyTextView = (TextView) view.findViewById(android.R.id.empty);
emptyTextView.setTextSize(10);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
adapter = new PlaceAdapter(getActivity(), placeList);
setListAdapter(adapter);
}
}
and my fragment_list.xml file
<?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">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#android:id/list" />
<TextView android:id="#id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="No data"/>
</LinearLayout>
When i will give input in edittext box and call place api and then parse json data. I have written Place class and then add place object in list. so please someone tell me that how to display empty text. app is showing exception in arrayadapter.getCount() method.
Your placeList is never initialized.
Moreover, in onCreateView(), you should probably create your view like this:
View view = inflater.inflate(R.layout.fragment_list, container, false);
I've been trying to open an activity from a fragment using the OnClick element in a TableRow but when I run the application it closes when trying to open the activity.
This is the Java code file:
package com.hello.turidf;
import com.hello.turidf.R;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class TabsIndexM001Help extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.m_001_help, container, false);
return rootView;
}
public void open_m001_map(View view) {
Intent openmap = new Intent(getActivity(),M001MapActivity.class);
startActivity(openmap);
}
}
This is the XML code file (fragment):
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
.......>
<TableLayout
.......>
<TabelRow
android:onClick="open_m001_map"
....>
........
</TableRow>
</TableLayout>
</ScrollBiew>
In 'M001MapActivity' activity has not yet been modified, has the code created by default.
android:onClick execute the method passed like parameter in Activity and not in Fragment. If you want execute this method in fragment, remove this line and set OnClickListener programatically on fragment.