java - 抽屉导航,它的 fragment 按钮找不到正确的 Action 监听器

标签 java android fragment actionlistener drawerlayout

抽屉导航有一些问题。我已经尝试了很多并在谷歌上搜索了很多但没有找到解决方案。 我正在使用抽屉导航。在那里你必须用 fragment 填充它的框架布局。 这很好用,例如: 我在抽屉导航中选择了一些东西,它的框架布局加载了带有按钮和 TextView 的 fragment (在我的应用程序中开始显示)。 现在我点击其中一个 fragment 按钮,这应该调用 fragment java 类 (startdisplay.java) 中的 Action 监听器,但它没有找到这些 Action 监听器(android studio 还告诉我这些从未使用过)。我发现该应用程序正在查看抽屉导航类(我的应用程序中的 mainmenuactivity)。

我的问题是我的应用程序是否可以直接在 fragment java 类中查找,因为我不能将所有代码放在一个类 (mainmenuactivity) 中。当然,这不会是我必须放入其中的唯一 fragment 。

代码如下: Startdisplay fragment 的 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="de.touristenfahrerforum.MarcelMoiser.Fragments.Startdisplay">

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <Button
        android:id="@+id/startButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="114dp"
        android:onClick="startButton"
        android:text="Start"
        android:textSize="50sp" />
....

Startdisplay fragment 的java类:

public class Startdisplay extends Fragment
{
....
private Activity activity;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    View view = inflater.inflate(R.layout.fragment_startdisplay, container, false);

    loadTrackText   = (TextView)view.findViewById(R.id.loadTrackText);
    loadModeText    = (TextView)view.findViewById(R.id.loadModeText);
    loadBestlapText = (TextView)view.findViewById(R.id.loadBestlapText);

    fileService = new Fileservice();

    activity = this.getActivity();

    return view;
}
....
/**
 * Actionlistener für den Start Button
 */
public void startButton(View view)    //!!!!!!!!!!!!!!This method should be called when the button is pressed <-------------------------------------------------------------
{
    if(track != null)
    {
        if( ((LocationManager) activity.getSystemService(activity.LOCATION_SERVICE)).isProviderEnabled(LocationManager.GPS_PROVIDER))
        {//GPS ist aktiviert
            Intent intent = new Intent(activity, MainActivity.class);

            intent.putExtra(V.TRACK_EXTRA, track);  //Hier könnte man vll auch nur den String statt dem Objekt übergeben <------
            intent.putExtra(V.MODE_EXTRA, mode);
            intent.putExtra(V.BESTLAP_EXTRA, bestlap);

            startActivity(intent);
        }
        else{}//Meldung geben das das GPS nicht aktiviert ist
    }
    else{}//else es muss erst eine Strecke geladen werden
}
....

主菜单 XML(抽屉布局):

    <?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_menu"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </FrameLayout>

    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111" />

</android.support.v4.widget.DrawerLayout>

以及 Mainmenuactivity(应用程序在其中搜索 startButton Action 监听器):

public class MainMenuActivity extends Activity
{
    private String[] menuItems;
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;

    private CharSequence mTitle;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_menu);

        //Standartwerte für die Einstellungen erzeugen
        PreferenceManager.setDefaultValues(this, R.xml.preferences, false);

        mTitle = getTitle();
        menuItems = new String[]{"Peter","Susi","Elephant"};
        mDrawerLayout = (DrawerLayout) findViewById(R.id.main_menu);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        //Holt sich den Wert für die Umrechnung zwischen PX und DP
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        V.LOGICAL_DENSITY = metrics.density;

        // Set the adapter for the list view
        mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.drawer_list_item, menuItems));
        // Set the list's click listener
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
    }

    /* The click listner for ListView in the navigation drawer */
    private class DrawerItemClickListener implements ListView.OnItemClickListener
    {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id)
        {
            selectItem(position);
        }
    }

    /** Swaps fragments in the main content view */
    private void selectItem(int position)
    {
        // Create a new fragment and specify the planet to show based on position


        // Insert the fragment by replacing any existing fragment
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame, new Startdisplay())
        .commit();

        // Highlight the selected item, update the title, and close the drawer
        mDrawerList.setItemChecked(position, true);
        setTitle(menuItems[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    @Override
    public void setTitle(CharSequence title)
    {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }
}

我只是在测试,所以 menuItems 没有任何意义,无论我点击什么,它总是加载 Startdisplay fragment 。所以就像我已经说过的,应用程序应该在 Startdisplay.java 中使用 actionlistener,而不应该在 MainMenuActivity.java 中搜索它。 提前致谢

最佳答案

您的问题是当您设置属性android:onClick 时,会在此 View 的上下文中查找该方法。 View 的上下文当然是 Activity 而不是 fragment ,这就是为什么 Android 无法在那里找到您的方法的原因。所以你有两个选择:

  1. 将方法放入 Activity 中并委托(delegate)给 fragment 。
  2. 使用View.OnClickListener相反。

总的来说,我个人不太喜欢使用 android:onClick,因为它很容易出错。如果它不起作用,它就会默默地失败,就像你的情况一样。因此,我会使用第二种方式。

在 fragment 的 onCreateView() 中调用这样的东西:

view.findViewById(R.id.startButton).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //Do what you need
    }
});

关于java - 抽屉导航,它的 fragment 按钮找不到正确的 Action 监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26085301/

相关文章:

java - 在 Java 8 中一行访问 List<List<Person>> 中的 Person 对象的每个名称

java - JOOQ 在 orderBy 方法中结合 Field 和 SortField?

android - 如何使用 Intents 将对象从一个 Android Activity 发送到另一个?

android - 无法使用 Instagram sdk Intent 分享故事

android - 将数据从 Fragment Activity 传输到 Fragment

android - 如何在选项卡中设置图像/图标而不是文本?

android - Fragment addToBackStack 关闭 App

Java:StringBuffer 和串联

java - 如何引用子类作为类型参数?

SQLite 安卓 NDK