This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I tried creating a simple app "MemeCrater" which i learned from one of youtube tutorial.but whenever i press the Create button.The App crashes.
This is the error i get.
Error
Process: com.example.iemshekhar.memegenerator, PID: 13118
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.iemshekhar.memegenerator.TopSectionFragment$TopSectionListener.createMeme(java.lang.String, java.lang.String)' on a null object reference
at com.example.iemshekhar.memegenerator.TopSectionFragment.buttonClicked(TopSectionFragment.java:57)
at com.example.iemshekhar.memegenerator.TopSectionFragment$1.onClick(TopSectionFragment.java:49)
at android.view.View.performClick(View.java:5697)
at android.widget.TextView.performClick(TextView.java:10815)
at android.view.View$PerformClick.run(View.java:22526)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
This is my main activity java file:
MainActivity.java
package com.example.iemshekhar.memegenerator;
import android.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends ActionBarActivity implements TopSectionFragment.TopSectionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void createMeme(String top, String bottom) {
BottomPictureFragment bottmfragment=(BottomPictureFragment)getFragmentManager().findFragmentById(R.id.fragment2);
bottmfragment.setMemeText(top,bottom);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
This is my top Fragement java file:
TopSectionFragment.java
package com.example.iemshekhar.memegenerator;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class TopSectionFragment extends Fragment {
private static EditText top, bottom;
TopSectionListener activitycommander;
public interface TopSectionListener{
public void createMeme(String top,String bottom);
}
public void onAtttach(Context context)
{
try{
activitycommander=(TopSectionListener)context;
}
catch(ClassCastException e){
throw new ClassCastException(e.getMessage());
}
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.top_section_fragment, container, false);
top = (EditText)view.findViewById(R.id.toptextinput);
bottom = (EditText) view.findViewById(R.id.bottomtextinput);
final Button create = (Button) view.findViewById(R.id.createbutton);
create.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
buttonClicked(v);
}
}
);
return view;
}
public void buttonClicked(View v) {
activitycommander.createMeme(top.getText().toString(),bottom.getText().toString());
}
}
This file is my bottom Fragment java File:
BottomSectionFragment.java
package com.example.iemshekhar.memegenerator;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by IEmShekhar on 6/18/2016.
*/
public class BottomPictureFragment extends Fragment {
public static TextView toptext,bottomtext;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bottom_picture_fragment, container, false);
toptext=(TextView)view.findViewById(R.id.textView1);
bottomtext=(TextView)view.findViewById(R.id.textView2);
return view;
}
public void setMemeText(String top,String bottom){
toptext.setText(top);
bottomtext.setText(bottom);
}
}
These are my XML Files:
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:background="#006669"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<fragment
android:layout_width="wrap_content"
android:layout_height="290dp"
android:name="com.example.iemshekhar.memegenerator.BottomPictureFragment"
android:id="#+id/fragment2"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
tools:layout="#layout/bottom_picture_fragment" />
<fragment
android:layout_width="400dp"
android:layout_height="wrap_content"
android:name="com.example.iemshekhar.memegenerator.TopSectionFragment"
android:id="#+id/fragment"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
tools:layout="#layout/top_section_fragment"
android:layout_above="#+id/fragment2" />
</RelativeLayout>
Top_section_Fragment.xml
<?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" android:background="#999999">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/toptextinput"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:width="300dp"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/bottomtextinput"
android:layout_centerHorizontal="true"
android:layout_below="#+id/toptextinput"
android:width="300dp"
android:layout_marginTop="30dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="150dp"
android:layout_centerHorizontal="true"
android:text="#string/Create_text"
android:background="#006666"
android:textStyle="bold"
android:id="#+id/createbutton"/>
</RelativeLayout>
Bottom_picture_Fragement.xml
<?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"
android:background="#drawable/afaque">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/toptext"
android:textStyle="bold"
android:textSize="25sp"
android:background="#ffff"
android:width="400dp"
android:textAlignment="center"
android:id="#+id/textView1"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/bottomtext"
android:textStyle="bold"
android:textSize="25sp"
android:background="#ffff"
android:width="400dp"
android:textAlignment="center"
android:id="#+id/textView2"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
Guessing that you're trying to set the text from editText, You should be accessing the text from your editText in your TopSectionFragment
Replace
//Initialize
`private static TextView top, bottom;`
//onCreateView() Method
top = (TextView) view.findViewById(R.id.textView1);
bottom = (TextView) view.findViewById(R.id.textView2);
with this
//Initialize
`private static EditText top, bottom;`
//onCreateView Method
//onCreateView() Method
top = (EditText) view.findViewById(R.id.toptextinput);
bottom = (EditText) view.findViewById(R.id.bottomtextinput);
in your TopSectionFragment. Hope this will help :)
Related
Hey guys I am a beginner in Android Develpoment. I am currently learning Navigation Components, but stuck in this app. I am setting listener to the button present in the activity_main.xml inside the FirstFragment.java and SecondFragment.java but my app crashes. I don't know what I am doing wrong.
Main Activity.java
package com.ahstore.inventory;
import android.os.Bundle;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.ahstore.inventory.databinding.ActivityMainBinding;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration appBarConfiguration;
private ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
binding.fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:theme="#style/Theme.Inventory.AppBarOverlay"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:popupTheme="#style/Theme.Inventory.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<HorizontalScrollView
android:id="#+id/horizontalScrollView"
android:layout_width="409dp"
android:layout_height="50dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:scrollIndicators="none"
android:scrollbarAlwaysDrawHorizontalTrack="false"
android:scrollbarAlwaysDrawVerticalTrack="false"
android:scrollbars="none"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/appBarLayout">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
</HorizontalScrollView>
<fragment
android:id="#+id/nav_host_fragment_content_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/horizontalScrollView"
app:navGraph="#navigation/nav_graph" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="#android:drawable/ic_input_add"
tools:ignore="SpeakableTextPresentCheck,SpeakableTextPresentCheck" />
</androidx.constraintlayout.widget.ConstraintLayout>
FirstFragment.java
package com.ahstore.inventory;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.ahstore.inventory.databinding.FragmentFirstBinding;
public class FirstFragment extends Fragment {
private FragmentFirstBinding binding;
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
View view=inflater.inflate(R.layout.fragment_first,container,false);
return view;
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button button1=view.findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
}
});
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
fragment_first.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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="match_parent"
tools:context=".FirstFragment">
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="First" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
SecondFragment.java
package com.ahstore.inventory;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.ahstore.inventory.databinding.FragmentSecondBinding;
public class SecondFragment extends Fragment {
private FragmentSecondBinding binding;
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
View view=inflater.inflate(R.layout.fragment_second,container,false);
return view;
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button button=view.findViewById(R.id.button2);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(SecondFragment.this)
.navigate(R.id.action_SecondFragment_to_FirstFragment);
}
});
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
fragment_second.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="#+id/cl"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondFragment">
<TextView
android:id="#+id/textview_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="am second"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Error
2022-03-04 16:54:11.473 2392-2392/com.ahstore.inventory E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ahstore.inventory, PID: 2392
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ahstore.inventory/com.ahstore.inventory.MainActivity}: android.view.InflateException: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3800)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3976)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2315)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8550)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: android.view.InflateException: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #79 in com.ahstore.inventory:layout/activity_main: Error inflating class fragment
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.ahstore.inventory.FirstFragment.onViewCreated(FirstFragment.java:35)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2987)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:392)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:140)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:319)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:298)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
at com.ahstore.inventory.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:75)
at com.ahstore.inventory.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:69)
at com.ahstore.inventory.MainActivity.onCreate(MainActivity.java:32)
at android.app.Activity.performCreate(Activity.java:8198)
2022-03-04 16:54:11.474 2392-2392/com.ahstore.inventory E/AndroidRuntime: at android.app.Activity.performCreate(Activity.java:8182)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3773)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3976)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2315)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8550)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Here are a few points that will help you understand your issue better
Your activity and fragments have their own respective layout files (xmls)
View are bound within their layout files. Simply put, if an element with id, say A, is present in activity_main.xml, then it can only be accessed when the layout being inflated is activity_main.xml. If the contentView of your Activity is activity_main.xml, it will be able to access all Views inside the layout file.
In fragments, the layout is inflated in the onCreateView method, which returns the resulting View for the Fragment. The findViewById(id) method is called against that View object. The method will look for the View with the given id inside that View only. If it is able to find the View it will return it, else it will return null. Same goes for finding a View inside an Activity (you do not need to specify the View for an Activity as it will automatically reference the layout that is specified in setContentView).
Now that we have the above points cleared, we can see the issue that you are facing. Firstly, the buttons with ids button1 and button2 are in your activity_main.xml layout file. However you are trying to access these from your Fragment1 and Fragment2 classes. But your Fragment1 and Fragment2 classes have their own layout files which do not have the two buttons. So, when you try to retrieve the buttons (using findViewById), it returns null because the buttons are not present in the layout. You then try to set a click listener. Since, the button object is null, calling any method on it will result in a Null Pointer Exception being throw.
We now understand what you are doing wrong. Now, how do we fix this. First you need to understand what it is you want to achieve. In this case I would suggest that you move both buttons to the respective Fragment layouts i.e. the View with id button1 will go to Fragment1 and the View with id button2 will go to Fragment2. This should help resolve the NPE that you are facing.
Still there are some cases where a Fragment might want to access a View that is present in its parent Activity. One of the ways to do this would be to
Create a public method in your Activity class which returns a View with the given id.
public View getViewById(int id) {
return findViewById(id);
}
Use this method in your Fragment by doing so
((MainActivity) getActivity()).getViewById(R.id.button1)
Other approaches involve using Interfaces which I am sure you will learn about as you continue learning more.
Just to wrap things up, you have two ways to go about fixing your issue. Either move the buttons to the fragment layout files or create a public method to retrieve those views.
I'm currently making a soundboard app on android studio which has a ton of fragments. The first page on my tab layout is just a normal button view, but my second tabView has another fragmentView within it. The goal is for the first page to just show some normal sounds, and the second tab to have multiple operators to choose specific soundboards for.
Anyways, the app seems to work fine. I can switch from the main tab to the operator tab, and even select operator soundboard pages and be moved to their fragments. However as soon as I try to switch fragments (through my tabview) my app crashes and I get the error:
"Fragment operatorTab{4623fc9} (312d4e58-458c-4f47-8fa3-794fe15f0536)} not attached to a context."**
**at com.jkcarraher.rainbowsixsoundboard.operatorTab.resetAllButtons(operatorTab.java:113)
at com.jkcarraher.rainbowsixsoundboard.operatorTab.access$000(operatorTab.java:31)
at com.jkcarraher.rainbowsixsoundboard.operatorTab$2.onScrollChanged(operatorTab.java:107)
I attached my code below, please let me know if you have any ideas!
MainActivity.java
import android.graphics.Color;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.widget.Adapter;
import android.widget.TextView;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import com.google.android.material.tabs.TabLayout;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private SectionsPageAdapter mSectionsPageAdapter;
private ViewPager mViewPager;
private TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeAds();
makeSixYellow();
//Create ViewPager (that houses all fragments)
mSectionsPageAdapter = new SectionsPageAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.view_pager);
setUpViewPager(mViewPager);
//Add & customize tabs
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setTabTextColors(Color.WHITE, Color.WHITE);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setText("Utility");
tabLayout.getTabAt(1).setText("Voice Lines");
checkPageChange();
}
private void setUpViewPager(ViewPager viewPager) {
SectionsPageAdapter adapter = new SectionsPageAdapter(getSupportFragmentManager());
adapter.addFragment(new utilityTab(), "Utility");
adapter.addFragment(new voiceLinesView(), "Voice Lines");
viewPager.setAdapter(adapter);
}
private void makeSixYellow(){
TextView textView = findViewById(R.id.titleText);
String text = "R6 Soundboard";
SpannableString ss = new SpannableString(text);
ForegroundColorSpan fcsYellow = new ForegroundColorSpan(Color.rgb(255,236,141));
ss.setSpan(fcsYellow, 1,2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(ss);
}
private void initializeAds(){
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
}
});
}
private void checkPageChange(){
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
utilityTab.resetAllButtons();
}
#Override
public void onPageSelected(int position) {
utilityTab.resetAllButtons();
}
#Override
public void onPageScrollStateChanged(int state) {
utilityTab.resetAllButtons();
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorHeader"
android:theme="#style/AppTheme.AppBarOverlay">
<TextView
android:id="#+id/titleText"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/avenir"
android:gravity="center_horizontal"
android:text="R6 Soundboard"
android:textColor="#FFF"
android:textSize="30sp" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextColor="#fff"
android:background="#color/colorHeader" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorBody"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
voiceLinesView.java (contains fragments so I can select an operator and it will take me to their soundboard fragment)
package com.jkcarraher.rainbowsixsoundboard;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.material.tabs.TabLayout;
public class voiceLinesView extends Fragment {
private SectionsPageAdapter voiceLinesSectionsPageAdapter;
private ViewPager voiceLinesViewPager;
public voiceLinesView() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_voice_lines_view, container, false);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.voiceLinesFrame, new operatorTab());
fragmentTransaction.commit();
return view;
}
}
fragment_voice_lines_view.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".voiceLinesView">
<FrameLayout
android:id="#+id/voiceLinesFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
operatorTab.java
package com.jkcarraher.rainbowsixsoundboard;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Rect;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import soup.neumorphism.NeumorphCardView;
import soup.neumorphism.ShapeType;
import static android.view.MotionEvent.ACTION_MOVE;
public class operatorTab extends Fragment {
private ScrollView scrollView;
public static RelativeLayout KapkanButton;
public static RelativeLayout GlazButton;
public static RelativeLayout FuzeButton;
public static RelativeLayout TachankaButton;
voiceLinesView voiceLinesView = new voiceLinesView();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_operator_tab, container, false);
//Initialize ScrollView
scrollView = view.findViewById(R.id.operatorScrollView);
//Initialize buttons 1-4
KapkanButton = view.findViewById(R.id.kapkanButton);
GlazButton = view.findViewById(R.id.glazButton);
FuzeButton = view.findViewById(R.id.fuzeButton);
TachankaButton = view.findViewById(R.id.tachankaButton);
//Make buttons 1-6 pressable
initPressableButton(KapkanButton);
initPressableButton(GlazButton);
initPressableButton(FuzeButton);
initPressableButton(TachankaButton);
scrollResetListener();
return view;
}
#SuppressLint("ClickableViewAccessibility")
private void initPressableButton(final RelativeLayout relativeLayout) {
relativeLayout.setBackgroundColor(getResources().getColor(R.color.colorBody));
final Rect r = new Rect();
relativeLayout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
// get the View's Rect relative to its parent
view.getHitRect(r);
// offset the touch coordinates with the values from r
// to obtain meaningful coordinates
final float x = event.getX() + r.left;
final float y = event.getY() + r.top;
if(event.getAction() == MotionEvent.ACTION_DOWN) {
relativeLayout.setBackgroundColor(getResources().getColor(R.color.colorButtonPressed));
return true;
} else if(event.getAction() == MotionEvent.ACTION_UP) {
if (r.contains((int) x, (int) y)) {
relativeLayout.setBackgroundColor(getResources().getColor(R.color.colorBody));
//On Click Up
FragmentTransaction fr = getFragmentManager().beginTransaction();
fr.replace(R.id.voiceLinesFrame, new kapkanVoiceLines());
fr.commit();
}
}else if(event.getAction() == ACTION_MOVE){
if (!r.contains((int) x, (int) y)) {
relativeLayout.setBackgroundColor(getResources().getColor(R.color.colorBody));
}
return true;
}
return false;
}
});
}
private void scrollResetListener(){
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
resetAllButtons();
}
});
}
public void resetAllButtons(){
KapkanButton.setBackgroundColor(getResources().getColor(R.color.colorBody));
GlazButton.setBackgroundColor(getResources().getColor(R.color.colorBody));
FuzeButton.setBackgroundColor(getResources().getColor(R.color.colorBody));
TachankaButton.setBackgroundColor(getResources().getColor(R.color.colorBody));
}
}
fragment_operator_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".operatorTab">
<ScrollView
android:id="#+id/operatorScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorBody">
<RelativeLayout
android:id="#+id/kapkanButton"
android:layout_width="match_parent"
android:layout_height="60sp"
android:orientation="horizontal">
<ImageView
android:id="#+id/kapkanIcon"
android:layout_width="50sp"
android:layout_height="50sp"
android:layout_marginTop="5sp"
android:layout_marginLeft="10sp"
android:src="#drawable/ic_kapkan"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/kapkanIcon"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:layout_gravity="center"
android:fontFamily="#font/avenir"
android:text="Kapkan"
android:textColor="#ffffff"
android:textSize="25dp" />
<ImageView
android:layout_width="40sp"
android:layout_height="40sp"
android:layout_alignParentEnd="true"
android:layout_marginTop="10sp"
android:layout_marginEnd="10dp"
android:src="#drawable/ic_arrow_right" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/glazButton"
android:layout_below="#+id/kapkanButton"
android:layout_width="match_parent"
android:layout_height="60sp"
android:orientation="horizontal">
<ImageView
android:id="#+id/glazIcon"
android:layout_width="50sp"
android:layout_height="50sp"
android:layout_marginTop="5sp"
android:layout_marginLeft="10sp"
android:src="#drawable/ic_glaz"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/glazIcon"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:layout_gravity="center"
android:fontFamily="#font/avenir"
android:text="Glaz"
android:textColor="#ffffff"
android:textSize="25dp" />
<ImageView
android:layout_width="40sp"
android:layout_height="40sp"
android:layout_alignParentEnd="true"
android:layout_marginTop="10sp"
android:layout_marginEnd="10dp"
android:src="#drawable/ic_arrow_right" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/fuzeButton"
android:layout_below="#+id/glazButton"
android:layout_width="match_parent"
android:layout_height="60sp"
android:orientation="horizontal">
<ImageView
android:id="#+id/fuzeIcon"
android:layout_width="50sp"
android:layout_height="50sp"
android:layout_marginTop="5sp"
android:layout_marginLeft="10sp"
android:src="#drawable/ic_fuze"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/fuzeIcon"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:layout_gravity="center"
android:fontFamily="#font/avenir"
android:text="Fuze"
android:textColor="#ffffff"
android:textSize="25dp" />
<ImageView
android:layout_width="40sp"
android:layout_height="40sp"
android:layout_alignParentEnd="true"
android:layout_marginTop="10sp"
android:layout_marginEnd="10dp"
android:src="#drawable/ic_arrow_right" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/tachankaButton"
android:layout_below="#+id/fuzeButton"
android:layout_width="match_parent"
android:layout_height="60sp"
android:orientation="horizontal">
<ImageView
android:id="#+id/tachankaIcon"
android:layout_width="50sp"
android:layout_height="50sp"
android:layout_marginTop="5sp"
android:layout_marginLeft="10sp"
android:src="#drawable/ic_tachanka"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/tachankaIcon"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:layout_gravity="center"
android:fontFamily="#font/avenir"
android:text="Tachanka"
android:textColor="#ffffff"
android:textSize="25dp" />
<ImageView
android:layout_width="40sp"
android:layout_height="40sp"
android:layout_alignParentEnd="true"
android:layout_marginTop="10sp"
android:layout_marginEnd="10dp"
android:src="#drawable/ic_arrow_right" />
</RelativeLayout>
</RelativeLayout>
</ScrollView>
</FrameLayout>
Try to remove the ViewTreeObserver.OnScrollChangedListener when the fragment is destroyed this will avoid any listener that can be attached to a destroyed fragment context not to be triggered whenever you leave and come back to this fragment.
First: make a global field for the listener
public class operatorTab extends Fragment {
...
ViewTreeObserver.OnScrollChangedListener mScrollListener = new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
resetAllButtons();
}
};
Then set the listener wit the created field
private void scrollResetListener(){
scrollView.getViewTreeObserver().addOnScrollChangedListener(mScrollListener);
}
Then remove the listener.. I believe it's typically should be in onDestroyView() >> but also try it in onStop() or onPause if it didn't work
This also will solve memory leak of this listener whenever its callback is triggered after the Fragment's view is destroyed
#Override
public void onDestroyView() {
super.onDestroyView();
scrollView.getViewTreeObserver().removeOnScrollChangedListener(mScrollListener);
}
UPDATE
onStop()/onPause() worked for me
The reason that it didn't work with onDestroyView() because the OperatorTab fragment is a part of one of the ViewPager pages; and by default ViewPager loads a number of close pages in the background to be ready for the next page scroll; loading this pages include some of the fragment lifecycle callbacks like onCreateView, onStart, but not onResume.
When you leave the OperatorTab by scrolling the ViewPager to the next tab/page; onDestroyView() won't be created if the ViewPager decides that OperatorTab is a part of the cached/close pages that the user might return back to it later; and therefore the listener still there and after a few swipes of the pager, the OperatorTab fragment can be detached from the context leaving the listener there with memory leaks...
So, the best way in ViewPager fragment (or any View that loads its fragments in advance) is to stop any listeners once you leave the page, i.e. in onPause or onStop callbacks and not waiting until they are destroyed.
A possible reason for this error is that you are calling getResources() NOT in an Activity without using a context. So, you need to use context.getResources() instead where context may be one of these here . In you instance, I think getContext() will work.
So, I think you should search for all the times you are calling getResources and see if you are using a context or not.
The explanation for this error in a simple way is that you are trying to access the context required in getResources() before the fragment is instantiated.
This is my first attempt to develop an android application.
I have a MainActivity with ConstraintLayout that has BottomNavigationView. Whenever the first navigation item is selected, I want to display a list of category (displayed in a fragment), then whenever this category is selected, another list will be displayed for items related to that particular category (in another fragment).
I have read in (Android - fragment .replace() doesn't replace content - puts it on top) it states that "static fragments written in XML are unable to be replaced, it has to be in a fragment container", how does it look like?
I tried to create my fragment container, but there is something wrong when I try to get the ListView (grand child of the container)
categoriesListView = getView().findViewById(R.id.categoriesList);
returns null.
MainActivity
package com.alsowaygh.getitdone.view.main;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.widget.TextView;
import com.alsowaygh.getitdone.R;
import com.alsowaygh.getitdone.view.services.CategoriesListFragment;
import com.alsowaygh.getitdone.view.services.OnCategorySelectedListener;
import com.alsowaygh.getitdone.view.services.ServicesListFragment;
public class MainActivity extends AppCompatActivity implements OnCategorySelectedListener {
private static final String TAG = "MainActivity";
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_services:
// mTextMessage.setText(R.string.title_services);
CategoriesListFragment categoriesListFragment = new CategoriesListFragment();
fragmentTransaction.add(R.id.container, categoriesListFragment);
fragmentTransaction.commit();
return true;
case R.id.navigation_bookings:
// mTextMessage.setText(R.string.title_bookings);
return true;
case R.id.navigation_chats:
// mTextMessage.setText(R.string.title_chats);
return true;
case R.id.navigation_settings:
return true;
}
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
}
#Override
public void onCategorySelected(String category) {
Log.w(TAG, "Successfully created CategoryListFragment!");
}
}
activity_main layout
<?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:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.main.MainActivity">
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation" />
</android.support.constraint.ConstraintLayout>
Fragment
package com.alsowaygh.getitdone.view.services;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.alsowaygh.getitdone.R;
import com.alsowaygh.getitdone.view.main.MainActivity;
public class CategoriesListFragment extends Fragment {
private ListView categoriesListView;
OnCategorySelectedListener categoryListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
//initializing root view first to refer to it
View rootView = inflater.inflate(R.layout.activity_main, container, false);
//initializing ListView
categoriesListView = getView().findViewById(R.id.categoriesList);
//categories list
final String[] categories = {"first category", "second category", "third category", "Fourth category"};
//initializing and adding categories strings to the addapter
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this.getContext(),
R.layout.category_textview);
for (String c : categories) {
arrayAdapter.add(c);
}
categoriesListView.setAdapter(arrayAdapter);
//implement onListItemClick
categoriesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//retrieve string from categories list at clicked position
categoryListener.onCategorySelected(categories[position]);
}
});
return rootView;
}
#Override //to fource container activity to implement the OnCategorySelectedListener
public void onAttach(Context context) {
super.onAttach(context);
try{
categoryListener = (OnCategorySelectedListener) context;
}catch(ClassCastException e){
throw new ClassCastException(context.toString() + "must implement OnCategorySelectedListener");
}
}
}
fragments container
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/categories_list_fragment"
android:name="com.alsowaygh.getitdone.view.services.CategoriesListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp">
<ListView
android:id="#+id/categoriesList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp" />
</fragment>
</FrameLayout>
Your help will be much appreciated.
You need to add the FrameLayout container within the layout file of the MainActivity(activity_main), onclick of the buttons in BottomNavigationView replace with the fragment. In this way you have a Activity and the fragments are shown within the activity, on click of each menu item you can invoke to replace it with the fragments.
This should resolve your problem.
You need to change the layout as below in activity_main.xml.
<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:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.main.MainActivity">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation" />
</android.support.constraint.ConstraintLayout>
In the MainActivity code, you need to change as below:
case R.id.navigation_services:
// mTextMessage.setText(R.string.title_services);
CategoriesListFragment categoriesListFragment = new CategoriesListFragment();
fragmentTransaction.replace(R.id.frame, categoriesListFragment);
fragmentTransaction.commit();
return true;
In the fragment layout file change to LinearLayout:
<LinearLayout
android:id="#+id/categories_list_fragment"
android:name="com.alsowaygh.getitdone.view.services.CategoriesListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp">
<ListView
android:id="#+id/categoriesList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp" />
</LinearLayout>
EDIT
In the fragment code, change the layout to the name of the fragment layout file(R.layout.fragment_layout_name).
View rootView = inflater.inflate(R.layout.fragment_layout_name, container, false);
//initializing ListView
categoriesListView = rootView.findViewById(R.id.categoriesList);
I'm making a program for Android using Eclipse. Here is my code for MainAcitvity.java:
package com.example.changeme;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
Button set = (Button)findViewById(R.id.set);
TextView out = (TextView)findViewById(R.id.out);
EditText in = (EditText)findViewById(R.id.input);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
set.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
setcontent();
}
});
}
public void setcontent()
{
String con = in.getText().toString();
out.setText(con);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return false;
}
}
Layout for main activity :
<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=".MainActivity" >
<TextView
android:id="#+id/out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/set"
android:layout_alignParentBottom="true"
android:layout_marginBottom="37dp"
android:text="#string/Change"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/set"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/input"
android:layout_centerHorizontal="true"
android:layout_marginTop="18dp"
android:text="#string/Set" />
<EditText
android:id="#+id/input"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="37dp"
android:ems="10"
android:inputType="textPersonName" />
It crashes when I run the program on my N4.
You need to inflate your layout before retrieve your elements, otherwise findViewById will return null and hence the line set.setOnClickListener(/**/); will throw a NullPointerException which make your app crashing.
Button set;
TextView out;
EditText in;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //<-- the layout is inflated, i.e it's rendered
/******************************************************/
//Now you can retrieve your elements from this layout
set = (Button)findViewById(R.id.set);
out = (TextView)findViewById(R.id.out);
in = (EditText)findViewById(R.id.input);
/*****************************************************/
set.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
setcontent();
}
});
}
I am new to android development, was following a tutorial in order to get a better understanding about fragments, but after completing the tutorial when it comes to testing I encountered this particular problem after removing a few syntax errors. In the logcat I get "threadid=1: thread exiting with uncaught exception (group=0x40a7193" I've spent almost an entire working day on it, I've looked but it seems like the solution to this problem is dependent upon the source code, I've been on a number of links but everywhere there's some source code provided and I haven't found a solution for my problem so far, any help will be much appreciated. Here is My Code:
MainActivity.java:
package com.example.fragmentsexample;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
public class MainActivity extends FragmentActivity implements ToolbarFragments.ToolbarListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onButtonClick(int fontsize, String text) {
TextFragment textFragment =
(TextFragment) getSupportFragmentManager().findFragmentById(R.id.text_fragment);
textFragment.changeTextProperties(fontsize, text);
}
}
Here is TextFragment.java:
package com.example.fragmentsexample;
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.TextView;
public class TextFragment extends Fragment {
private static TextView textview;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.text_fragment, container,false);
textview=(TextView) view.findViewById(R.id.textView1);
return view;
}
public void changeTextProperties(int fontsize, String text){
textview.setTextSize(fontsize);
textview.setText(text);
}
}
Here is ToolbarFragments.java
package com.example.fragmentsexample;
import android.app.Activity;
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.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class ToolbarFragments extends Fragment {
private static int seekvalue=10;
private static EditText editText;
ToolbarListener activityCallback;
public interface ToolbarListener {
public void onButtonClick(int position, String text);
}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
try{
activityCallback=(ToolbarListener) activity;
}
catch (Exception e){
throw new ClassCastException(activity.toString()+ "must implement ToolbarListener");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle SavedInstanceState){
View view=inflater.inflate(R.layout.toolbar_fragment, container, false);
editText=(EditText) view.findViewById(R.id.editText1);
final SeekBar seekbar=(SeekBar) view.findViewById(R.id.seekBar1);
seekbar.setOnSeekBarChangeListener((OnSeekBarChangeListener) this);
final Button button=(Button) view.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonClicked(v);
}
});
return view;
}
public void buttonClicked(View v){
activityCallback.onButtonClick(seekvalue,editText.getText().toString());
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser){
seekvalue=progress;
}
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
}
Here is the 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"
tools:context=".MainActivity" >
<fragment
android:id="#+id/toolbar_fragment"
android:name="com.example.fragmentexample.ToolbarFragments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
tools:layout="#layout/toolbar_fragment" />
<fragment
android:id="#+id/text_fragment"
android:name="com.example.fragmentexample.TextFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
tools:layout="#layout/text_fragment" />
</RelativeLayout>
Here is the text_fragment.xml:
<?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/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/fragtwo"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Here is the toolbar_fragment.xml
<?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" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/seekBar1"
android:layout_centerHorizontal="true"
android:layout_marginTop="17dp"
android:text="#string/button"/>
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:ems="10"
android:inputType="text" >
<requestFocus />
</EditText>
<SeekBar
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/editText1"
android:layout_marginTop="14dp" />
</RelativeLayout>
Any help any sort of help will be appreciated it is my second post here i apologize for a messy post