从Fragment类的外部更新视图的arrayAdapter

时间:2016-05-16 12:52:27

标签: java android android-fragments android-studio

我正在关注Udacity开发的Android应用程序课程,这个课程到目前为止还算不错。

只是为了尝试新事物,我决定对代码进行一些修改以整理它。

原始代码基本上包含一个类扩展Android的Fragment类,它还包括另一个类,用于从openweathermap.org API获取天气数据,在一个单独的线程中。

我决定在单独的课程上移动通信,演示和API转换功能,因为它最初太杂乱了(再次,这只是为了自我教育目的。原始代码工作得很好)。

现在我有一个ForecastFragment类:

public class ForecastFragment extends Fragment {

    ArrayAdapter<String> mForecastAdapter;

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

        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        //This is just a placeholder until we fetch the real data from web
        String[] data = {"Fetching data from server"};

        List<String> forecast = new ArrayList<String>(Arrays.asList(data));

        mForecastAdapter = new ArrayAdapter(
                getActivity(),
                R.layout.list_item_forecast,
                R.id.list_item_forecast_textview,
                data);

        ListView listView = (ListView) rootView.findViewById(R.id.listViewForecast);
        listView.setAdapter(mForecastAdapter);

        return rootView;
    }
}

我还有另外两个班级:

从服务器获取纯JSON的人

public class Comm extends AsyncTask<String, Void, String> {

    protected String doInBackground(String... params) {
        //Network operations 
        return responseFromServer;
    }

   protected void onPostExecute(String s) {
        super.onPostExecute(s);
        //Here should come the code which should update the view
    }
}

另一个将JSON转换为String [](ApiConverter类)。我正在跳过这个细节,因为它运作得很好。它基本上采用原始JSON字符串并返回一个字符串数组。

现在,问题是,由于Comm类在另一个线程上完成其主要工作,我必须更新Comm.onPostExecute()中的视图。否则主线程在Comm类执行它之前执行所有代码并且我得到一个空字符串。

我认为将ForecastFragment的onCreateView代码复制到Comm类,但感觉我违反了DRY原则。此外,ForecastFragment类已经实例化了Array Adapter的副本,用复制的代码实例化另一个是浪费资源。

我笨拙地试图编写代码来获取ForecastFragment的当前实例,但几乎没有失败。

我还尝试按照here说明将ForecastFragment更改为单身。似乎父级Fragment类阻止我这样做(我不确定即使我能做到,我也能完成我想要的)。

我可以将Comm类编写为ForecastFragment的子类,并从那里到达类变量,但是我想知道在保持类分离时是否有更好的方法。

那么,在保持通信和表示类分离的同时,实现这一目标的合理方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以创建界面,其中包含您在任务完成时要调用的方法

Fragment应该实现这个接口

AsyncTask应该采用类的实例来实现这个接口,在我们的例子中,calss将是ForecastFragment。

在任务中,onPostExecute()调用该方法onTaskComplete()

界面:

public interface TaskCompleteListener {
    public void onTaskComplete(String dataArray);
}

<强> ForecastFragment:

public class ForecastFragment extends Fragment implements TaskCompleteListener {

    ArrayAdapter<String> mForecastAdapter;

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

        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        //This is just a placeholder until we fetch the real data from web
        //String[] data = {"Fetching data from server"};

        new Comm(this).execute("params...");

        return rootView;
    }

    @override
    public void onTaskComplete(String dataArray){
        data = parseJson(dataArray);
        List<String> forecast = new ArrayList<String>(Arrays.asList(data));
        mForecastAdapter = new ArrayAdapter(
                getActivity(),
                R.layout.list_item_forecast,
                R.id.list_item_forecast_textview,
                data);

        ListView listView = (ListView) rootView.findViewById(R.id.listViewForecast);
        listView.setAdapter(mForecastAdapter);
    }
}

任务Comm:

public class Comm extends AsyncTask<String, Void, String> {
    private TaskCompleteListener taskCompleteListener = null;

    public Comm(TaskCompleteListener taskCompleteListener){
        this.taskCompleteListener = taskCompleteListener;
    }

    protected String doInBackground(String... params) {
        //Network operations 
        return responseFromServer;
    }

   protected void onPostExecute(String s) {
        super.onPostExecute(s);
        //Here should come the code which should update the view
        taskCompleteListener.onTaskComplete(s);
    }
}