1

我是android编程的新手。我想创建一个带有一些 textview 和按钮的自定义进度对话框,并使用两个 progressBar显示进度并在从Asynctask发送文件时更新它们,另外我希望它与最低 API 10 一起使用。google doc 建议我使用DialogFragment我这样做不知道如何更新我的 fragmentDialog 自定义布局中的进度条和文本视图,当我尝试引用文本视图或进度条时,它会抛出空异常

这是我的代码

public static class FireMissilesDialogFragment extends DialogFragment {
    public FireMissilesDialogFragment(){
    }
    public static FireMissilesDialogFragment newInstance(String title) {
        FireMissilesDialogFragment frag = new FireMissilesDialogFragment();
        Bundle args = new Bundle();
        args.putString("title", title);
        frag.setArguments(args);
        return frag;
    }
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // Get the layout inflater
        LayoutInflater inflater = this.getActivity().getLayoutInflater();
        // Inflate and set the layout for the dialog
        // Pass null as the parent view because its going in the dialog layout

        View view = inflater.inflate(R.layout.custom_progress, null);
        ProgressBar pbCurrent = (ProgressBar) view.findViewById(R.id.current);

        builder.setView(view);

        builder.setMessage("Fire Missiles")
        .setPositiveButton("Fire", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                // FIRE ZE MISSILES!
            }
        })
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                // User cancelled the dialog
            }
        });
        // Create the AlertDialog object and return it
        return builder.create();
    }
}

尝试引用视图时,我的主要活动中出现了 nullExeption

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

    Button frag = (Button) findViewById(R.id.frag);
    frag.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FireMissilesDialogFragment fragment = FireMissilesDialogFragment.newInstance("hi") ;
            fragment.getActivity().findViewById(R.id.current);// nullExeption here
            //              downloadAsync as = new downloadAsync();
            //              as.execute();

        }
    });

我没有看到太多关于这个的问题和例子,我是不是一直走错了,应该选择另一种方式来实现我的观点??!!

编辑:我正在尝试创建这样的东西

提前致谢

4

1 回答 1

1

我不能做一个完整的解释,但我可以留下一个例子,然后希望你能找到一种方法来整合你需要的东西。

带有 AsyncTask 和进度条的 DialogFragment:

public class LoadHydrantsToMapTaskFragment extends DialogFragment {

    public static final String TAG = LoadHydrantsToMapTaskFragment.class
            .getSimpleName();

    public interface LoadHydrantsToMapTaskCallback {
        void onPreExecute(int maxProgress);

        void onProgressUpdate(int progress);

        void onCancelled();

        void onPostExecute();
    }

    private LoadHydrantsToMapTask mTask;
    // private ProgressBar mProgressBar;

    private List<HydrantHolder> mHydrants;

    private GoogleMap map;

    public static LoadHydrantsToMapTaskFragment newInstance(
            List<HydrantHolder> hydrants, GoogleMap map) {
        LoadHydrantsToMapTaskFragment taskFragment = new LoadHydrantsToMapTaskFragment();
        taskFragment.mHydrants = hydrants;
        taskFragment.map = map;

        return taskFragment;
    }

    @Override public void onAttach(Activity activity) {
        super.onAttach(activity);

    }

    @Override public View onCreateView(LayoutInflater inflater,
            ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.dialog_progress_task, container);
        mProgressBar = (ProgressBar) view.findViewById(R.id.progressBar);
        mProgressBar.setProgress(0);
        mProgressBar.setMax(mHydrants.size());

        getDialog().setTitle(getActivity().getString(R.string.adding_hydrants));
        // This dialog can't be canceled by pressing the back key.
        getDialog().setCancelable(false);
        getDialog().setCanceledOnTouchOutside(false);

        return view;
    }

    /**
     * This method will only be called once when the retained Fragment is first
     * created.
     */
    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(SherlockDialogFragment.STYLE_NORMAL, R.style.TuriosDialog);

        // Retain this fragment across configuration changes.
        setRetainInstance(true);

        mTask = new LoadHydrantsToMapTask(mHydrants);
        mTask.setCallback(new LoadHydrantsToMapTaskCallback() {

            @Override public void onPreExecute(int maxProgress) {
            }

            @Override public void onProgressUpdate(int progress) {
                mProgressBar.setProgress(progress);
            }

            @Override public void onPostExecute() {
                if (isResumed())
                    dismiss();

                mTask = null;

            }

            @Override public void onCancelled() {
                if (isResumed())
                    dismiss();

                mTask = null;
            }
        });

        mTask.execute();
    }

    @Override public void onResume() {
        super.onResume();

        // This is a little hacky, but we will see if the task has finished
        // while we weren't
        // in this activity, and then we can dismiss ourselves.
        if (mTask == null)
            dismiss();
    }

    @Override public void onDetach() {
        super.onDetach();
    }

    // This is to work around what is apparently a bug. If you don't have it
    // here the dialog will be dismissed on rotation, so tell it not to dismiss.
    @Override public void onDestroyView() {
        if (getDialog() != null && getRetainInstance())
            getDialog().setDismissMessage(null);
        super.onDestroyView();
    }

    // Also when we are dismissed we need to cancel the task.
    @Override public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        // If true, the thread is interrupted immediately, which may do bad
        // things.
        // If false, it guarantees a result is never returned (onPostExecute()
        // isn't called)
        // but you have to repeatedly call isCancelled() in your
        // doInBackground()
        // function to check if it should exit. For some tasks that might not be
        // feasible.
        if (mTask != null)
            mTask.cancel(false);

    }

    private class LoadHydrantsToMapTask extends
            AsyncTask<Void, Integer, List<MarkerOptions>> {
        // Before running code in separate thread
        List<HydrantHolder> mHydrants;
        LoadHydrantsToMapTaskCallback mLoadHydrantsToMapTaskCallback;

        public LoadHydrantsToMapTask(List<HydrantHolder> hydrants) {
            this.mHydrants = hydrants;
        }

        public void setCallback(
                LoadHydrantsToMapTaskCallback loadHydrantsToMapTaskCallback) {
            this.mLoadHydrantsToMapTaskCallback = loadHydrantsToMapTaskCallback;
        }

        @Override protected void onPreExecute() {

            if (mLoadHydrantsToMapTaskCallback != null) {
                mLoadHydrantsToMapTaskCallback.onPreExecute(mHydrants.size());
            }

        }

        // The code to be executed in a background thread.
        @Override protected List<MarkerOptions> doInBackground(Void... arg) {
            List<MarkerOptions> markers = new ArrayList<MarkerOptions>();

            for (HydrantHolder hydrant : mHydrants) {

                final String hydrant_type = hydrant.getHydrantType();
                final String hydrant_icon_path = hydrant.getIconPath();
                double latitude = hydrant.getLatitude();
                double longitude = hydrant.getLongitude();

                final LatLng position = new LatLng(latitude, longitude);

                final String address = hydrant.getAddress();
                final String addressNumber = hydrant.getAddressNumber();
                final String addressremark = hydrant.getAddressRemark();
                final String remark = hydrant.getRemark();

                // Log.d(TAG, hydrant.toString());

                BitmapDescriptor icon = BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_RED);

                if (!hydrant_icon_path.isEmpty()) {
                    File iconfile = new File(hydrant_icon_path);
                    if (iconfile.exists()) {
                        BitmapDescriptor loaded_icon = BitmapDescriptorFactory
                                .fromPath(hydrant_icon_path);
                        if (loaded_icon != null) {
                            icon = loaded_icon;
                        } else {
                            Log.e(TAG, "loaded_icon was null");
                        }
                    } else {
                        Log.e(TAG, "iconfile did not exist: "
                                + hydrant_icon_path);
                    }
                } else {
                    Log.e(TAG, "iconpath was empty on hydrant type: "
                            + hydrant_type);
                }

                StringBuffer snippet = new StringBuffer();
                if (!address.isEmpty())
                    snippet.append("\n" + address + " " + addressNumber);
                if (addressremark.isEmpty())
                    snippet.append("\n" + addressremark);
                if (!remark.isEmpty())
                    snippet.append("\n" + remark);

                markers.add(new MarkerOptions().position(position)
                        .title(hydrant_type).snippet(snippet.toString())
                        .icon(icon));

                publishProgress(markers.size());
            }
            return markers;
        }

        // Update the progress
        @Override protected void onProgressUpdate(Integer... values) {
            if (mLoadHydrantsToMapTaskCallback != null) {
                mLoadHydrantsToMapTaskCallback.onProgressUpdate(values[0]);
            }
        }

        @Override protected void onCancelled() {
            if (mLoadHydrantsToMapTaskCallback != null) {
                mLoadHydrantsToMapTaskCallback.onCancelled();
            }
        }

        // after executing the code in the thread
        @Override protected void onPostExecute(List<MarkerOptions> markers) {

            for (MarkerOptions marker : markers) {
                if (marker != null && map != null)
                    map.addMarker(marker);
            }

            if (mLoadHydrantsToMapTaskCallback != null) {
                mLoadHydrantsToMapTaskCallback.onPostExecute();
            }

        }

    }

}

我的 dialog_progress_task 布局:

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

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:maxHeight="10dip"
        android:minHeight="10dip"
        android:progress="0"
        android:progressDrawable="@drawable/progress_orange" />

</LinearLayout>

最后是我用来添加它的代码:

@Override public void loadHydrantsToMap(List<HydrantHolder> hydrants,
        GoogleMap map) {

    LoadHydrantsToMapTaskFragment loadHydrantsFragment;

    if (fm != null) {
        FragmentTransaction ft = fm.beginTransaction();
        loadHydrantsFragment = (LoadHydrantsToMapTaskFragment) fm
                .findFragmentByTag(LoadHydrantsToMapTaskFragment.TAG);
        if (loadHydrantsFragment != null) {
            Log.i("Attatching LoadHydrantsToMapTaskFragment");
            ft.attach(loadHydrantsFragment);
        } else {
            loadHydrantsFragment = LoadHydrantsToMapTaskFragment
                    .newInstance(hydrants, map);
            Log.i("Adding new LoadHydrantsToMapTaskFragment");
            ft.add(loadHydrantsFragment, LoadHydrantsToMapTaskFragment.TAG);
        }
        ft.commit();
    }
}
于 2014-02-21T13:57:01.707 回答