android片段类中的全局变量不起作用

时间:2014-01-22 18:28:10

标签: android variables android-fragments global

我的Android应用程序存在一些问题。我使用fragement来显示两个日期选择器和一个调用活动中的方法的按钮,然后该方法调用datepicker值的getter。 问题是,作为getter的方法总是为所选日期选择器项返回null。日期选择器对象由onCreateView方法中的findViewById调用,并设置为类变量。在那里,可以找到该对象,并且在该方法中可以获得所选值。 但是当我尝试使用getter方法中的值时,从外部调用类变量,日期选择器始终设置为null。我不明白这个问题,经过近两天的搜索,我希望你能帮助我。

这是片段xml布局:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textLabelStartDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/label_startDate" />

    <DatePicker
        android:id="@+id/datePickerStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:calendarViewShown="false" />

    <TextView
        android:id="@+id/textLabelEndDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/label_endDate" />

    <DatePicker
        android:id="@+id/datePickerEnd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:calendarViewShown="false" />

    <Button
        android:id="@+id/calculate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="23dp"
        android:onClick="calculateSelectedAverageData"
        android:text="@string/button_calculate" />

</LinearLayout>

这是活动中的方法(按下按钮时调用):

public void calculateSelectedAverageData(View view) {
    FitnessDateFragment dateFragment = (FitnessDateFragment) mPagerAdapter
            .getItem(1);
    System.out.println(dateFragment.getStartDate());
    System.out.println(dateFragment.getEndDate());
    Toast.makeText(this, "New data for selected time created",
            Toast.LENGTH_LONG).show();
}

这是我的片段(onViewCreated datePicker值不是null但是在getter方法中):

public class FitnessDateFragment extends Fragment {

    private LinearLayout fragmentLayout;

    DatePicker datePickerStart;
    DatePicker datePickerEnd;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        fragmentLayout = (LinearLayout) inflater.inflate(
                R.layout.activity_fitness_date_fragment, container, false);
        datePickerStart = (DatePicker) getActivity().findViewById(
                R.id.datePickerStart);
        datePickerEnd = (DatePicker) getActivity().findViewById(
                R.id.datePickerEnd);
        return fragmentLayout;
    }

    public long getStartDate() {
        Calendar calendarStart = new GregorianCalendar(
                datePickerStart.getYear(), datePickerStart.getMonth(),
                datePickerStart.getDayOfMonth());
        return calendarStart.getTimeInMillis();
    }

    public long getEndDate() {
        Calendar calendarEnd = new GregorianCalendar(datePickerEnd.getYear(),
                datePickerEnd.getMonth(), datePickerEnd.getDayOfMonth());
        return calendarEnd.getTimeInMillis();
    }
}

使用例外记录:

01-22 20:00:29.485: W/dalvikvm(24195): threadid=1: thread exiting with uncaught exception (group=0x40d78a08)
01-22 20:00:29.490: E/AndroidRuntime(24195): FATAL EXCEPTION: main
01-22 20:00:29.490: E/AndroidRuntime(24195): java.lang.IllegalStateException: Could not execute method of the activity
01-22 20:00:29.490: E/AndroidRuntime(24195):    at android.view.View$1.onClick(View.java:3626)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at android.view.View.performClick(View.java:4231)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at android.view.View$PerformClick.run(View.java:17537)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at android.os.Handler.handleCallback(Handler.java:725)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at android.os.Looper.loop(Looper.java:158)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at android.app.ActivityThread.main(ActivityThread.java:5751)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at java.lang.reflect.Method.invokeNative(Native Method)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at java.lang.reflect.Method.invoke(Method.java:511)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1083)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:850)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at dalvik.system.NativeStart.main(Native Method)
01-22 20:00:29.490: E/AndroidRuntime(24195): Caused by: java.lang.reflect.InvocationTargetException
01-22 20:00:29.490: E/AndroidRuntime(24195):    at java.lang.reflect.Method.invokeNative(Native Method)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at java.lang.reflect.Method.invoke(Method.java:511)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at android.view.View$1.onClick(View.java:3621)
01-22 20:00:29.490: E/AndroidRuntime(24195):    ... 11 more
01-22 20:00:29.490: E/AndroidRuntime(24195): Caused by: java.lang.NullPointerException
01-22 20:00:29.490: E/AndroidRuntime(24195):    at com.uni.fitnesstracker.FitnessDateFragment.getStartDate(FitnessDateFragment.java:36)
01-22 20:00:29.490: E/AndroidRuntime(24195):    at com.uni.fitnesstracker.FitnessGUI.calculateSelectedAverageData(FitnessGUI.java:101)
01-22 20:00:29.490: E/AndroidRuntime(24195):    ... 14 more

编辑FitnessGUI:

我跳过了这一点,我正在使用ViewPager在三个碎片之间滑动:

protected void onCreate(Bundle savedInstanceState){     super.onCreate(savedInstanceState);

setContentView(R.layout.activity_fitness_recorder);


mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mPagerAdapter);

// Service Connection
Intent intent = new Intent(this, FitnessService.class);
bindService(intent, connectedService, Context.BIND_AUTO_CREATE);
isBound = true;

// Elements for data
averageDataForPieChart = new FitnessDataAverage[3];

}

主xml如下:

<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.PagerTitleStrip
        android:id="@+id/pager_title_strip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#33b5e5"
        android:paddingBottom="4dp"
        android:paddingTop="4dp"
        android:textColor="#fff" />

</android.support.v4.view.ViewPager>

PagerAdapter:

package com.uni.fitnesstracker;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class PagerAdapter extends FragmentPagerAdapter {
    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    public Fragment getItem(int position) {
        Fragment result;
        Bundle args = new Bundle();
        args.putInt("position", position);
        switch (position) {
        case 0:
            result = new FitnessRecorderFragment();
            break;
        case 1:
            result = new FitnessDateFragment();
            break;
        case 2:
            result = new FitnessResultFragment();
            break;
        default:
            result = new FitnessRecorderFragment();
            break;
        }
        result.setArguments(args);
        return result;
    }

    public int getCount() {
        return 3;
    }

    public CharSequence getPageTitle(int position) {
        String result;
        switch (position) {
        case 0:
            result = "Recorder";
            break;
        case 1:
            result = "Date";
            break;
        case 2:
            result = "Result";
            break;
        default:
            result = "Recorder";
            break;
        }
        return result;
    }
}

2 个答案:

答案 0 :(得分:0)

如果您使用的是“静态”日期并且没有更改以填充您的选择器而不是为什么不通过包中的参数将其传递给您的片段并将它们放入片段onCreate中。

答案 1 :(得分:0)

您的datePickerStartdatePickerEnd都为空。在调用这些方法之前,您需要检查片段是否已附加。

而不是使用System.out.println使用Log.i

实施例

public class MainActivity extends Activity {
    FitnessDateFragment fragment;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragment = new FitnessDateFragment();
        fragmentTransaction.add(R.id.container, fragment);
        fragmentTransaction.commit();
    }
    public void calculateSelectedAverageData(View view) {
        if(fragment.isAdded())
        Log.i("Start date is",""+fragment.getStartDate());
        Log.i("End date is",""+fragment.getEndDate());
        Toast.makeText(this, "New data for selected time created",
                Toast.LENGTH_LONG).show();
    }
}

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container">
    </FrameLayout>
</RelativeLayout>

frag.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textLabelStartDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="label_startDate" />

    <DatePicker
        android:id="@+id/datePickerStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:calendarViewShown="false" />

    <TextView
        android:id="@+id/textLabelEndDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="label_endDate" />

    <DatePicker
        android:id="@+id/datePickerEnd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:calendarViewShown="false" />

    <Button
        android:id="@+id/calculate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="23dp"
        android:onClick="calculateSelectedAverageData"
        android:text="button_calculate" />

</LinearLayout>

FitnessFragment

public class FitnessDateFragment extends Fragment {

    private LinearLayout fragmentLayout;

    DatePicker datePickerStart;
    DatePicker datePickerEnd;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        fragmentLayout = (LinearLayout) inflater.inflate(
                R.layout.frag, container, false);
        datePickerStart = (DatePicker) fragmentLayout.findViewById(
                R.id.datePickerStart);
        datePickerEnd = (DatePicker) fragmentLayout.findViewById(
                R.id.datePickerEnd);
        return fragmentLayout;
    }

    public long getStartDate() {
        Calendar calendarStart = new GregorianCalendar(
                datePickerStart.getYear(), datePickerStart.getMonth(),
                datePickerStart.getDayOfMonth());
        return calendarStart.getTimeInMillis();
    }

    public long getEndDate() {
        Calendar calendarEnd = new GregorianCalendar(datePickerEnd.getYear(),
                datePickerEnd.getMonth(), datePickerEnd.getDayOfMonth());
        return calendarEnd.getTimeInMillis();
    }
}