异步任务类完成后如何更改文本视图的值(在片段中)?

Posted

技术标签:

【中文标题】异步任务类完成后如何更改文本视图的值(在片段中)?【英文标题】:How to change value of textview(in fragment) after Async Task class Completes? 【发布时间】:2017-02-09 12:58:21 【问题描述】:

我是 android 编程的初学者,这是我迄今为止最大的项目。请尽量在你的答案中非常具体,因为这一切对我来说都是全新的。 我想要做的是在 OneFragment 的文本视图中显示天气(描述)的值。`

这里是 MainActivity

package com.example.dell.myop;

import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;


import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

import com.example.dell.myop.R;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


import com.example.dell.myop.fragments.OneFragment;

import com.example.dell.myop.fragments.ThreeFragment;
import com.example.dell.myop.fragments.TwoFragment;

public class MainActivity extends AppCompatActivity 

    private Toolbar toolbar;
    private TabLayout tabLayout;
    private ViewPager viewPager;
    String description;

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

        DownloadTask task = new DownloadTask();
        task.execute("http://api.openweathermap.org/data/2.5/weather?q=hamirpur,india&appid=41352ca35dd1be72cc7d9f47351d1b41");

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        viewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(viewPager);

        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);
    

    private void setupViewPager(ViewPager viewPager) 
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(new OneFragment(), "Today");
        adapter.addFragment(new TwoFragment(), "Tomorrow");
        adapter.addFragment(new ThreeFragment(), "Day After");
        viewPager.setAdapter(adapter);
    

    class ViewPagerAdapter extends FragmentPagerAdapter 
        private final List<Fragment> mFragmentList = new ArrayList<>();
        private final List<String> mFragmentTitleList = new ArrayList<>();

        public ViewPagerAdapter(FragmentManager manager) 
            super(manager);
        

        @Override
        public Fragment getItem(int position) 
            return mFragmentList.get(position);
        

        @Override
        public int getCount() 
            return mFragmentList.size();
        

        public void addFragment(Fragment fragment, String title) 
            mFragmentList.add(fragment);
            mFragmentTitleList.add(title);
        

        @Override
        public CharSequence getPageTitle(int position) 
            return mFragmentTitleList.get(position);
        
    

下载任务

package com.example.dell.myop;

import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;

import com.example.dell.myop.fragments.OneFragment;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import static android.support.v4.app.ActivityCompat.startActivity;

public class DownloadTask extends AsyncTask<String,Void,String> 

    @Override
    protected String doInBackground(String... urls) 

        String result = "";
        URL url;
        HttpURLConnection urlConnection= null;

        try 
            url = new URL(urls[0]);
            urlConnection = (HttpURLConnection) url.openConnection();
            InputStream in = urlConnection.getInputStream();
            InputStreamReader reader = new InputStreamReader(in);
            int data = reader.read();
            while(data!=-1)
                char current = (char)data;
                result += current;
                data = reader.read();
            
            return  result;

         catch (MalformedURLException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
            

        return null;
    

    @Override
    protected void onPostExecute(String result) 
        super.onPostExecute(result);
        try 
            JSONObject jObject = new JSONObject(result);
            JSONArray jArray = jObject.getJSONArray("weather");
            for (int i=0; i < jArray.length(); i++)
            
                try 
                    JSONObject oneObject = jArray.getJSONObject(i);
                    // Pulling items from the array
                    String main = oneObject.getString("main");
                    String description = oneObject.getString("description");
                    Log.i("main",main);
                    Log.i("description",description);

                 catch (JSONException e) 
                    // Oops
                
            
         catch (JSONException e) 
            e.printStackTrace();
        
    

这里是一个片段

package com.example.dell.myop.fragments;

/**
 * Created by Dell on 13-09-2016.
 */
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.dell.myop.DownloadTask;
import com.example.dell.myop.MainActivity;
import com.example.dell.myop.R;

import com.example.dell.myop.R;


public class OneFragment extends Fragment

    public OneFragment() 

    

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        View view = inflater.inflate(R.layout.fragment_one, container, false);
        TextView textView = (TextView) view.findViewById(R.id.textView);

        textView.setText(description);
        return view;
        

【问题讨论】:

以下两个答案基本上都遵循这个答案***.com/questions/12575068/… 【参考方案1】:

我建议你将 downloadTask 的逻辑移到你的 Fragment 中,如果你只在这个中使用它的话。 这将非常容易,只需获取描述和设置:

textView.setText(description); in your fragment,

如果您想在 Activity 的其他组件上使用此 downloadTask,您必须在您的 Activity 上实现一些 CallBack 并在任何片段上使用它们来更新 UI。 所以让我们说在你的活动中你声明了一些接口

 interface OnDownloadTaskFinish 
 onFinish(String description);
 

用在

 onPostExecute(...)
 //...some logic here 
 getFragment..... .onFinish(description);
 

在你的 Fragment 中你应该实现这个接口并且

 void onFinish(String description)
 textView.setText(description);
 

【讨论】:

【参考方案2】:

1) 在您的DownloadTask 中创建一个interface,其setternotification code

private Listener listener;

public void setListener(Listener listener)
    this.listener = listener;


public interface Listener
    onCompleted(String description);


@Override
protected void onPostExecute(String result) 
    // Your Current Code

    if(listener != null) listener.onCompleted(description);

2) 在你的OneFragment中实现这个接口

public class OneFragment extends Fragment implements DownloadTask.Listener

     private TextView textView;

     @Override
     onCompleted(String description)
         if(description != null && textView !=null)
             textView.setDescription(description);
     

     // Other code

3) 创建global referenceOneFragment 并将其设置为Listener for DownloadTask in MainActivity as

private OneFragment oneFragment = new OneFragment();

4) 将adapter.addFragment(new OneFragment(), "Today"); 替换为adapter.addFragment(oneFragment, "Today");

5) 设置监听器为

DownloadTask task = new DownloadTask();
task.setListener(oneFragment);
task.execute("http://api.openweathermap.org/data/2.5/weather?q=hamirpur,india&appid=41352ca35dd1be72cc7d9f47351d1b41");

6) execute DowloadTaskviewPager.setAdapter(adapter); 之后会更好

【讨论】:

以上是关于异步任务类完成后如何更改文本视图的值(在片段中)?的主要内容,如果未能解决你的问题,请参考以下文章

当片段视图加载是异步任务的一部分时,如何在片段加载之前显示进度条?

当活动中的异步任务完成时如何在片段中重新加载ui?

在 TabLayout 和 ViewPager2 中执行异步任务后更新具有相同布局的多个片段

片段布局加载延迟

在 Swift 中,如何从异步任务外壳内部更新主线程上的文本视图

更改数组后无法在 Tableview 中重新加载数据?