使用 Navigation 访问 onClick 形成 Android 片段
Accessing onClick form an Android fragment using Navigation
我无法在片段中为我的按钮设置 onClick 侦听器。可能是上下文错了,但是我看不到。
请在下方提供帮助我认为我正在做所有事情好吗?我虽然理解上下文的工作原理,但在我看来,今天有用的东西明天就不行了?
片段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"
android:background="@color/colorPrimary"
tools:context=".OBWelcomeFragment">
<ImageView
android:id="@+id/imageView3"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="@drawable/logo_main"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.08" />
<ScrollView
android:id="@+id/scrollView3"
android:layout_width="324dp"
android:layout_height="333dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.494"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView3"
app:layout_constraintVertical_bias="0.594">
<TextView
android:id="@+id/tv_description_heading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/ob_welcome_text"
android:textColor="@color/cardview_light_background"
android:textSize="18sp" />
</ScrollView>
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="@string/app"
android:textColor="@color/cardview_light_background"
android:textSize="36sp"
app:layout_constraintBottom_toTopOf="@+id/scrollView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView3"
app:layout_constraintVertical_bias="0.18" />
<Button
android:id="@+id/oBlocationButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginLeft="32dp"
android:layout_marginEnd="32dp"
android:layout_marginRight="32dp"
android:layout_marginBottom="32dp"
android:onClick="onClick"
android:text="Next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/scrollView2" />
</androidx.constraintlayout.widget.ConstraintLayout>
对应片段
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.navigation.NavDirections;
import androidx.navigation.Navigation;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class OBWelcomeFragment extends Fragment implements View.OnClickListener {
public OBWelcomeFragment() {
// Required empty public constructor
}
public static OBWelcomeFragment newInstance(String param1, String param2) {
OBWelcomeFragment fragment = new OBWelcomeFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_o_b_welcome, container, false);
}
@Override
public void onClick(View v) {
NavDirections action =
OBWelcomeFragmentDirections.actionOBWelcomeFragmentToOBLocationFragment3();
Navigation.findNavController(v).navigate(action);
}
}
错误
2020-02-27 12:43:50.375 15523-15523/com.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.app, PID: 15523
java.lang.IllegalStateException: Could not find method onClick(View) in a parent or ancestor
Context for android:onClick attribute defined on view class
androidx.appcompat.widget.AppCompatButton with id 'oBlocationButton'
at
androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatView
Inflater.java:436)
at
androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflat .er.java:393)
at android.view.View.performClick(View.java:7259)
at android.view.View.performClickInternal(View.java:7236)
at android.view.View.access00(View.java:801)
at android.view.View$PerformClick.run(View.java:27892)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
如果您还需要什么,请告诉我?
问题是您正在执行这两项操作(虽然两者都不完整...),实施 OnClickListener
并在 xml
中定义了一个方法。做其中任何一项。
我会指定这两个,如果只在 xml 中执行,你必须在 xml 中指定你的 onClick()
方法,而不是
<Button
android:id="@+id/oBlocationButton"
....
android:onClick="onClick"/>
在您的片段中只需创建此方法:(不要实现侦听器)
public class OBWelcomeFragment extends Fragment {
....
// notice -> no override here..
public void onClick(View v) {
}
}
或者反过来:这次不在xml中指定onClick,而是找到按钮并设置监听器。
public class OBWelcomeFragment extends Fragment implements View.OnClickListener {
.....
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button btn = view.findViewById(R.id.oBlocationButton);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
NavDirections action = OBWelcomeFragmentDirections.actionOBWelcomeFragmentToOBLocationFragment3();
Navigation.findNavController(v).navigate(action);
}
}
我无法在片段中为我的按钮设置 onClick 侦听器。可能是上下文错了,但是我看不到。
请在下方提供帮助我认为我正在做所有事情好吗?我虽然理解上下文的工作原理,但在我看来,今天有用的东西明天就不行了?
片段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"
android:background="@color/colorPrimary"
tools:context=".OBWelcomeFragment">
<ImageView
android:id="@+id/imageView3"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="@drawable/logo_main"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.08" />
<ScrollView
android:id="@+id/scrollView3"
android:layout_width="324dp"
android:layout_height="333dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.494"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView3"
app:layout_constraintVertical_bias="0.594">
<TextView
android:id="@+id/tv_description_heading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/ob_welcome_text"
android:textColor="@color/cardview_light_background"
android:textSize="18sp" />
</ScrollView>
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="@string/app"
android:textColor="@color/cardview_light_background"
android:textSize="36sp"
app:layout_constraintBottom_toTopOf="@+id/scrollView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView3"
app:layout_constraintVertical_bias="0.18" />
<Button
android:id="@+id/oBlocationButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginLeft="32dp"
android:layout_marginEnd="32dp"
android:layout_marginRight="32dp"
android:layout_marginBottom="32dp"
android:onClick="onClick"
android:text="Next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/scrollView2" />
</androidx.constraintlayout.widget.ConstraintLayout>
对应片段
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.navigation.NavDirections;
import androidx.navigation.Navigation;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class OBWelcomeFragment extends Fragment implements View.OnClickListener {
public OBWelcomeFragment() {
// Required empty public constructor
}
public static OBWelcomeFragment newInstance(String param1, String param2) {
OBWelcomeFragment fragment = new OBWelcomeFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_o_b_welcome, container, false);
}
@Override
public void onClick(View v) {
NavDirections action =
OBWelcomeFragmentDirections.actionOBWelcomeFragmentToOBLocationFragment3();
Navigation.findNavController(v).navigate(action);
}
}
错误
2020-02-27 12:43:50.375 15523-15523/com.app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.app, PID: 15523
java.lang.IllegalStateException: Could not find method onClick(View) in a parent or ancestor
Context for android:onClick attribute defined on view class
androidx.appcompat.widget.AppCompatButton with id 'oBlocationButton'
at
androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatView
Inflater.java:436)
at
androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflat .er.java:393)
at android.view.View.performClick(View.java:7259)
at android.view.View.performClickInternal(View.java:7236)
at android.view.View.access00(View.java:801)
at android.view.View$PerformClick.run(View.java:27892)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
如果您还需要什么,请告诉我?
问题是您正在执行这两项操作(虽然两者都不完整...),实施 OnClickListener
并在 xml
中定义了一个方法。做其中任何一项。
我会指定这两个,如果只在 xml 中执行,你必须在 xml 中指定你的 onClick()
方法,而不是
<Button
android:id="@+id/oBlocationButton"
....
android:onClick="onClick"/>
在您的片段中只需创建此方法:(不要实现侦听器)
public class OBWelcomeFragment extends Fragment {
....
// notice -> no override here..
public void onClick(View v) {
}
}
或者反过来:这次不在xml中指定onClick,而是找到按钮并设置监听器。
public class OBWelcomeFragment extends Fragment implements View.OnClickListener {
.....
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button btn = view.findViewById(R.id.oBlocationButton);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
NavDirections action = OBWelcomeFragmentDirections.actionOBWelcomeFragmentToOBLocationFragment3();
Navigation.findNavController(v).navigate(action);
}
}