How can I open a fragment from a fragment with Cardview? I have a list of Cardview in fragment_home.xml and when i click in one of those want to show in another fragment.
Here is what i have so far.
fragment_home.xml
<androidx.cardview.widget.CardView
android:id="#+id/cvCocktails"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:cardCornerRadius="15dp"
app:cardElevation="0dp"
app:layout_columnWeight="1"
app:layout_rowWeight="1"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="Cocktails">
<ImageView
android:id="#+id/ivCocktails"
android:layout_width="115dp"
android:layout_height="115dp"
android:layout_centerInParent="true"
android:contentDescription="#string/cocktail"
android:src="#drawable/cocktail_color"
android:translationY="-15dp"
tools:ignore="VisualLintBounds" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/ivCocktails"
android:layout_centerHorizontal="true"
android:text="#string/cocktail"
android:textSize="20dp"
tools:ignore="SpUsage,TextSizeCheck" />
</RelativeLayout>
HomeFragment.java
public class HomeFragment extends Fragment {
public CardView cocktails;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home,container,false);
cocktails = view.findViewById(R.id.cvCocktails);
cocktails.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CocktailFragment cocktailFragment = new CocktailFragment();
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_home,cocktailFragment,null)
.addToBackStack(null).commit();
}
});
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
When i compile the app and click on Cocktail Cardview i have this error. How can i fix this. Thank you.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.barapp, PID: 11805
java.lang.IllegalStateException: Could not find method Cocktails(View) in a parent
or ancestor Context for android:onClick attribute defined on view class
android.widget.RelativeLayout
at android.view.View$DeclaredOnClickListener.resolveMethod(View.java:6302)
at android.view.View$DeclaredOnClickListener.onClick(View.java:6259)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Related
My Android app crashes when resuming after being killed by OS due to low memory.
So I have built the smallest possible app to reproduce the bug.
My app is composed of a MainActivity, which contains 1 page in a viewPager2, which contains a fragment.
This fragment is added dynamically by replacing "structure_placeholder" (in the real app, the type of fragment depends on some parameters)
MainActivity.java:
public class MainActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this);
ViewPager2 viewPage = findViewById(R.id.viewpager);
viewPage.setAdapter(sectionsPagerAdapter);
}
/***************************************************************************/
class SectionsPagerAdapter extends FragmentStateAdapter
{
private SectionsPagerAdapter(FragmentActivity fa)
{
super(fa);
}
#NonNull #Override
public Fragment createFragment(int position)
{
return new MyPageFragment();
}
#Override
public int getItemCount()
{
return 1;
}
}
}
activity_main.xml:
<LinearLayout
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">
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MyPageFragment.java:
public class MyPageFragment extends Fragment
{
public MyPageFragment()
{ /* Required empty public constructor*/}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.my_page_fragment, container, false);
}
#Override
public void onStart()
{
super.onStart();
Fragment listFragment = SubFragment.newInstance();
FragmentTransaction ft = requireActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.structure_placeholder, listFragment);
ft.commit();
}
}
my_page_fragment.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MyPageFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_blank_fragment" />
<FrameLayout
android:id="#+id/structure_placeholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:layout_width="100dp"
tools:layout_height="150dp"
tools:background="#color/design_default_color_secondary"
>
</FrameLayout>
</LinearLayout>
SubFragment.java:
public class SubFragment extends Fragment
{
public SubFragment()
{ /* Required empty public constructor*/ }
public static SubFragment newInstance()
{
SubFragment fragment = new SubFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.sub_fragment, container, false);
}
}
sub_fragment.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/line1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/line2" />
</LinearLayout>
Here is the error log when resuming the app after it has been killed:
2021-11-19 15:46:55.739 8298-8298/com.delrocq.mytestapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.delrocq.mytestapp, PID: 8298
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.delrocq.mytestapp/com.delrocq.mytestapp.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f0801db (com.delrocq.mytestapp:id/structure_placeholder) for fragment SubFragment{9eb5496} (ada1c808-c885-49ed-9cd3-f4de1855c6af id=0x7f0801db)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2957)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0801db (com.delrocq.mytestapp:id/structure_placeholder) for fragment SubFragment{9eb5496} (ada1c808-c885-49ed-9cd3-f4de1855c6af id=0x7f0801db)
I tried to put some logs to understand the lifecycle of the activity/fragments, but it did not help.
What am I doing wrong?
I finally found the solution after hours of searching and many wrong tracks.
Inside a fragment, getChildFragmentManager() shall be used instead of getSupportFragmentManager().
It is so easy when you know it :)
I've been searching the error for about 2 hours on google , i can't figure out what it's wrong . It just force closes when I tap the button "butonCap", I didn't work with fragments until now
ERROR:
java.lang.IllegalStateException: Could not find method butonCap(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'cap'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:423)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:380)
at android.view.View.performClick(View.java:6897)
at android.widget.TextView.performClick(TextView.java:12693)
at android.view.View$PerformClick.run(View.java:26101)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Butoane.java - i just made another java file because i can't write any code in the fragment java file
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_fata);
final Button butonCap = (Button) findViewById(R.id.cap);
butonCap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent butonCap = new Intent(Butoanele.this, capul.class);
Butoanele.this.startActivity(butonCap);
}
});
}
}
fragment_fata.xml - this is just one of the 2 fragments from navigation view
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".FragmentFata"
android:background="#drawable/fata">
<!-- TODO: Update blank fragment layout -->
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/cap"
android:layout_width="wrap_content"
android:layout_height="65dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:background="#drawable/button_outline"
android:paddingBottom="30dp"
android:onClick="butonCap"
android:text="Cap"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
You class should extends Fragment and inflate layout in onCreateView() callback.
Call getActivity().findViewById in onViewCreated() callback.
watch this guide
In fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_fata, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
if (getView() == null) {
return;
}
final Button butonCap = (Button) getView().findViewById(R.id.cap);
butonCap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getView().getContext(), capul.class);
startActivity(intent);
}
});
}
I have a very simple app with just one activity and a FrameLayout in it. I have two layout A and B and I am loading them as fragments one at a time thus replacing the current fragment. The problem is that when I press the back button the app crashes. The fragment change is triggered by a button in the first fragment
MainActivity.java
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
else {
// Create a new Fragment to be placed in the activity layout
SelectLogInFragment firstFragment = new SelectLogInFragment();
// In case this activity was started with special instructions from an
// Intent, pass the Intent's extras to the fragment as arguments
firstFragment.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).commit();
}
}
}
public void login_email(View view)
{
// Create fragment and give it an argument specifying the article it should show
Log_In_form newFragment = new Log_In_form();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
SelectLogInFragment.java
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SelectLogInFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.select_log_in, container, false);
}
}
LogInForm is very similar to SelectLogInFragment
select_log_in.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">
<fragment android:name="com.badass.david.mynewapplication.Top_Log"
android:id="#+id/top_log"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="0dp" />
<fragment android:name="com.badass.david.mynewapplication.Bottom_Log"
android:id="#+id/bottom_log"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
Top_Log.java
public class Top_Log extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.top_log, container, false);
}
}
Bottom_Log is very similar
top_log.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#color/white" >
<TextView
android:id="#+id/logo_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Put Logo here" />
</LinearLayout>
Errors
06-20 12:00:06.773 20327-20327/com.badass.david.mynewapplication
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.badass.david.mynewapplication, PID: 20327
android.view.InflateException: Binary XML file line #6: Error
inflating class fragment
at
android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
at
com.badass.david.mynewapplication.SelectLogInFragment.onCreateView(SelectLogInFragment.java:16)
at
android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at
android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:979)
at
android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1670)
at
android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:586)
at
android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:188)
at android.app.Activity.onKeyUp(Activity.java:2576)
at android.view.KeyEvent.dispatch(KeyEvent.java:3171)
at android.app.Activity.dispatchKeyEvent(Activity.java:2831)
at
com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2438)
at
android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4582)
at
android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4537)
at
android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
at
android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
at
android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
at
android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4201)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
at
android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4258)
at
android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
at
android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
at
android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
at
android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
at
android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
at
android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
at
android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4234)
at
android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4421)
at
android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2480)
at
android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:2074)
at
android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:2065)
at
android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2457)
at
android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:5951)
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:1388)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
Caused by: java.lang.IllegalArgumentException: Binary XML file line
6: Duplicate id 0x7f0c0089, tag null, or parent id 0xffffffff with another fragment for com.badass.david.mynewapplication.Top_Log
at
android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2293)
at android.support.v4.view.LayoutInflaterCompatHC$Factory
To me it seems like it is trying to create a fragment that already exists so there is an ID conflict.. Is it the problem? How can I solve it?
you should replace file select_log_in.xml by:
<?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">
<FrameLayout
android:id="#+id/top_log"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="0dp" />
<FrameLayout
android:id="#+id/bottom_log"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
and in the onCreateView method of SelectLogInFragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.select_log_in,null);
}
and in the onViewCreated method of SelectLogInFragment:
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewGroup topLogView = findViewById(R.id.top_log);
ViewGroup bottomLogView = findViewById(R.id.bottom_log);
if(topLogView != null){
topLogView.removeAllViews();
}
if(bottomLogView != null){
bottomLogView.removeAllViews();
}
getChildFragmentManager().beginTransaction().add(R.id.top_log,TopLogFragment,"top_log").commit();
getChildFragmentManager().beginTransaction().add(R.id.bottom_log,BottomLogFragment,"bottom_log").commit();
}
I'm having a hell of a time getting fragments to work. The basis of this is to lave a login screen (fragment) appear by default when LoginActivity is created. The fragment has an TextView that when clicked, is supposed to launch a new fragment (form for lost password). I keep getting a NullPointerException when calling forgottenPassword.setOnClickListener from LoginActivity.
The project crashes before I can tell if anything else works.
I'm sure there's some glaring newbie error in here somewhere...
onCreate method from LoginActivity.java:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
if (savedInstanceState == null) {
FragmentManager fragmentManager = getFragmentManager();
int fragmentTransaction = fragmentManager.beginTransaction()
.add(R.id.login_screen_fragment, new FragmentLogin())
.commit();
}
// Listen for FORGOTTEN PASSWORD click event, open ForgottenPassword Fragment //
final TextView forgottenPassword = (TextView) findViewById(R.id.button_lost_pass);
forgottenPassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do what I need this to do...
}
});
}
layout_login.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/login_screen_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity"
/>
fragment_login:
<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="come.xxxx.xxxx.ForgottenPasswordFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/login_email"
android:id="#+id/login_forgot"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="#string/login_send_lost_pass"
android:id="#+id/button_lost_pass"
/>
</LinearLayout>
</FrameLayout>
fragment_lost_password.xml:
<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="com.xxxx.xxx.FragmentLogin">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fitsSystemWindows="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:orientation="vertical"
android:layout_gravity="center"
android:focusable="true"
android:focusableInTouchMode="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I forgot my password"
android:gravity="center"
android:layout_marginTop="32dp"
android:padding="8dp"
android:textSize="16sp"
android:id="#+id/login_forgot"
/>
</LinearLayout>
</ScrollView>
</FrameLayout>
FragmentLogin.java:
public class FragmentLogin extends Fragment {
public FragmentLogin() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_login, container, false);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
final Activity activity = getActivity();
}
}
FragmentLostPassword.java
public class FragmentForgottenPassword extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_forgotten_password, container, false);
}
}
Error Trace:
05-13 12:49:37.222 15163-15163/com.xxxxx.xxxxx E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xxxxx.xxxxx, PID: 15163
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxxxx.xxxxx/com.xxxxx.xxxxx.LoginActivity}: 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:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
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:5254)
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.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.xxxxx.xxxxx.LoginActivity.onCreate(LoginActivity.java:51)
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:2387)
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:5254)
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)
05-13 12:50:28.592 15163-15173/com.xxxxx.xxxxx W/art: Suspending all threads took: 15.077ms
05-13 12:50:44.622 15163-15163/? I/Process: Sending signal. PID: 15163 SIG: 9
You have to find the View in your Fragment's layout.
Use the following in your FragmentLogin class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_login, container, false);
final TextView forgottenPassword = (TextView) view.findViewById(R.id.button_lost_pass);
// Set your onClickListener here
return view;
}
Actually, your fragment might be not accessible when you assign forgetpassword , you can use the following for layout_login.xml:
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:name="FragmentLogin"
tools:layout="#layout/fragment_login"
/>
Note you may have to define the right path to FragmentLogin.
This is the new way to work with fragment, that will load your Login fragment automatically without writing anything in onCreate.
Also, it's not a TextView but a Button
Finally, remove the Fragment Transaction code.
Another option, is to move your forgot password button login to FragmentLogin. Because basically you try to access Fragment related element from the activity. Everything should be in your fragment.
You can still access the fragment manager with getActivity().getFragmentManger(), to load the lost_password layout.
What is the activity_login.xml content. I guest wrong id of button button_lost_pass
Inside oncreate() method you called new Fragment but the fragment layout(layout_lost_password) does not contain the id(R.id.button_lost_pass)
Change :
final TextView forgottenPassword = (TextView) findViewById(R.id.button_lost_pass);
To
final Button forgottenPassword = (Button) findViewById(R.id.button_lost_pass);
I am not able to set the text from Homefragment.java
Currently I have below xml files:
activity_main.xml
<LinearLayout
android:id="#+id/tab_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<include
android:id="#+id/ftr"
layout="#layout/tab" />
</LinearLayout>
<LinearLayout
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</LinearLayout>
Now tab.xml
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/txt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</TableRow>
Now class files:
activity_main.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
initUI();
}
private void initUI() {
fragment = new HomeFragment();
}
HomeFragment.java
public class HomeFragment extends Fragment {
private TextView txt;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container,
false);
context = getActivity();
initUI(rootView);
return rootView;
}
private void initUI(View view) {
txt = (TextView)view.findViewbyid(R.id.txt1);
txt.setText("hello. test");
}
fragment_home.xml
<RelativeLayout 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"
>
....
</RelativeLayout
Error log:
Caused by: java.lang.NullPointerException
at com.xx.ew.fragment.HomeFragment.initUI(HomeFragment.java:112)
at com.xx.ew.fragment.HomeFragment.onCreateView(HomeFragment.java:99)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:548)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1174)
at android.app.Activity.performStart(Activity.java:5356)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2340)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5333)
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:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
Now the issue is When I am trying to set text of Textview of tab.xml in homefragment class then it is not set the text and force close the app.
How can set the text of textview(txt1) of tab.xml from homefragment.java ?
Changed my answer
Call your fragment as follows in initUI() method of activity:-
private void initUI() {
fragment = new HomeFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.replace(R.id.tab_bar, fragment);
fragmentTransaction.commit();
}
In Fragment change only one line which is in createView method
View rootView = inflater.inflate(R.layout.tab, container,
false);
MainActivity.java
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
if (fragment == null) {
fragment = new HomeFragment();
fm.beginTransaction().add(R.id.fragmentContainer, fragment)
.commit();
}
}
}
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
HomeFragment.java
public class HomeFragment extends Fragment {
private Context context;
private TextView txt;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container,
false);
context = getActivity();
initUI(rootView);
return rootView;
}
private void initUI(View view) {
txt = (TextView) view.findViewById(R.id.txt1);
txt.setText("hello. test");
}
}
fragment_home.xml
<RelativeLayout 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" >
<include
android:id="#+id/ftr"
layout="#layout/tab" />
</RelativeLayout>
Try:
Make rootView a global variable. And then override the onStart method and call initUI from there.