使用 asynctask 在所有 Fragment 中的 Activity 中显示 ListView

Posted

技术标签:

【中文标题】使用 asynctask 在所有 Fragment 中的 Activity 中显示 ListView【英文标题】:Show ListView in Activity in all Fragment with asynctask 【发布时间】:2018-05-15 03:52:28 【问题描述】:

我想显示一个 ListView 项目,代码来自我的活动,我想显示在我的所有片段中

我已经创建了一个这样的 Json

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() 

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) 
            Fragment selectedFragment = null;
            switch (item.getItemId()) 
                case R.id.navigation_home:
                    //mTextMessage.setText(namapegawai);
                    selectedFragment = PegawaiFragment.newInstance();
                    break;
                case R.id.navigation_dashboard:
                    //mTextMessage.setText(R.string.title_dashboard);
                    selectedFragment = MemberFragment.newInstance();
                    break;
                //case R.id.navigation_notifications:
                   // mTextMessage.setText(R.string.title_notifications);
                    //break;
            
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.frame_layout, selectedFragment);
            transaction.commit();
            return true;
        
    ;

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

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        namapegawai = prefs.getString(MainActivity.UserName,MainActivity.UserName);
        mTextMessage = findViewById(R.id.message);

        StudentListView = findViewById(R.id.listview1);
        progressBar = findViewById(R.id.progressBar);

        StudentListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
        
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 

                // TODO Auto-generated method stub
                //Intent intentSemuaMemberLihat = new Intent(getActivity(),SemuaMemberLihat.class);
                // Sending ListView clicked value using intent.
                //intentSemuaMemberLihat.putExtra("ListViewValue", IdList.get(position).toString());
                //startActivity(intentSemuaMemberLihat);
            
        );

        BottomNavigationView navigation = findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

        //Manually displaying the first fragment - one time only
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.frame_layout, PegawaiFragment.newInstance());
        transaction.commit();
    

// JSON parse class started from here.
    public class GetHttpResponse extends AsyncTask<Void, Void, Void>
    
        public Context context;

        String JSonResult;

        List<Member> studentList;

        public GetHttpResponse(Context context)
        
            this.context = context;
        

        @Override
        protected void onPreExecute()
        
            super.onPreExecute();
        

        @Override
        protected Void doInBackground(Void... arg0)
        
            // Passing HTTP URL to HttpServicesClass Class.
            HttpServicesClass httpServicesClass = new HttpServicesClass(HttpUrl);
            try
            
                httpServicesClass.ExecutePostRequest();

                if(httpServicesClass.getResponseCode() == 200)
                
                    JSonResult = httpServicesClass.getResponse();

                    if(JSonResult != null)
                    
                        JSONArray jsonArray = null;

                        try 
                            jsonArray = new JSONArray(JSonResult);

                            JSONObject jsonObject;
                            Member member;
                            studentList = new ArrayList<Member>();

                            for(int i=0; i<jsonArray.length(); i++)
                            
                                member = new Member();
                                jsonObject = jsonArray.getJSONObject(i);

                                // Adding Student Id TO IdList Array.
                                IdList.add(jsonObject.getString("id").toString());
                                //Adding Student Name.
                                member.nama = jsonObject.getString("nama").toString();
                                member.nrp = jsonObject.getString("nrp").toString();
                                studentList.add(member);

                                Fragment fragment = PegawaiFragment.newInstance();
                                Bundle bundle = new Bundle();
                                bundle.putString("name", member.nama);
                                fragment.setArguments(bundle);

                            
                        
                        catch (JSONException e) 
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        
                    
                
                else
                
                    Toast.makeText(context, httpServicesClass.getErrorMessage(), Toast.LENGTH_SHORT).show();
                
            
            catch (Exception e)
            
                // TODO Auto-generated catch block
                e.printStackTrace();
            
            return null;
        

        @Override
        protected void onPostExecute(Void result)

        
            progressBar.setVisibility(View.GONE);
            StudentListView.setVisibility(View.VISIBLE);

            if(studentList != null) 
                ListAdapterClass adapter = new ListAdapterClass(studentList, context);
                StudentListView.setAdapter(adapter);
            else
            
                Toast.makeText(context, "Tidak ada data ditampilkan", Toast.LENGTH_SHORT).show();
            

        
    

在我的片段中调用它

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

    new PegawaiActivity.GetHttpResponse(getActivity()).execute();

    return v;

得到这个错误

错误:(44, 9) 错误:需要包含 PegawaiActivity.GetHttpResponse 的封闭实例

围绕此代码

 new PegawaiActivity.GetHttpResponse(getActivity()).execute();

有人知道如何解决这个问题吗? 已经在其他相关的搜索,但仍然混淆理解它。 感谢您的帮助

============更新

我的简单异步任务

public class GetHttpResponse extends AsyncTask<Void, Void, Void>

    public AsyncResponse delegate = null;

    public interface AsyncResponse
        void onComplete(String output);
    

    @Override
    protected void onPostExecute(String result)
        delegate.onComplete(result);
    


在片段中

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

    getActivity().setTitle("Daftar Member");
    setHasOptionsMenu(true);

    StudentListView = v.findViewById(R.id.listview1);
    progressBar = v.findViewById(R.id.progressBar);

    PegawaiActivity a = new PegawaiActivity();
    PegawaiActivity.GetHttpResponse mm = a.new GetHttpResponse(new PegawaiActivity.GetHttpResponse.AsyncResponse()

        @Override
        public void onComplete(String output)
            progressBar.setVisibility(View.GONE);
        
    );
    mm.execute();


    return v;

但是给我错误

Error:(51, 49) 错误:类中的构造函数 GetHttpResponses PegawaiActivity.GetHttpResponses 不能应用于给定类型; 必需:未找到参数:原因:实际 和形式参数列表的长度不同

【问题讨论】:

必须是public static class GetHttpResponse 无论如何,您希望这能做什么?您正在循环中创建一个全新的 Fragment,然后立即将其丢弃... 我想要在我的所有片段中显示 ListView 项目数据,我错过了什么吗? 是的,有一些事情......顺便说一下,阅读minimal reproducible example。在所有 Fragment 中显示相同的列表视图与 JSON 或 Asynctasks 无关 【参考方案1】:

您的第一个错误是试图让您创建内部类public static class GetHttpResponse

您的第二个错误是告诉您,您将参数传递给 Asynctask 却没有为一个参数定义构造函数。


在我所有的片段中

对于初学者,您的 Asynctask 只是尝试设置一个 Fragment。

其次,您正在创建一个全新的,而不是在任何现有的中设置 ListView。


Fragment 可以访问属于 Activity 的任何数据。

例如,尝试让它在片段中工作

List<Member> studentList = ((PegawaiActivity) getActivity()).getStudents();

将学生列表字段移出 Asynctask 并移入父 Activity 后,您可以创建一个 getter 方法。


您不一定需要将 ListView 数据传递给任何 Fragment。不过,如果你这样做了,请查看How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

一旦您在 Activity 中返回结果,您将加载 Fragment,就像您已经尝试过的那样


无论选择哪种方式,都将在 Fragments 内部构建适配器,并将适配器设置在 Fragment 布局的 Listview 上,而不是现有的StudentListView,它是 Activity 布局的一部分,因此您无法在每个片段

【讨论】:

是的,但是我对如何实现它感到困惑,你能帮我编辑我的代码吗? 我无法更改我的 Asynctask 以获取接口代码,我更新了我的第一篇文章,你能帮忙 对于初学者,请退出使用嵌套类。 AsyncResponse 应该是一个完全独立的 Java 文件 其次,我假设您是 android 新手,并且没有研究任何其他方法来执行网络请求以获取 JSON?看看 Volley 或 Retrofit。 Asynctasks 代码太多,无法解决问题 最后,看起来你跳过了我的建议,开始在 Activity 上实现 getStudents() 方法......这不需要这个 AsyncResponse 东西

以上是关于使用 asynctask 在所有 Fragment 中的 Activity 中显示 ListView的主要内容,如果未能解决你的问题,请参考以下文章

打开新的 Fragment 和 AsyncTask 时显示 ProgressDialog

Asynctask结果显示重新创建片段后

从 Fragment 内的 AsyncTask 重新启动 Loader (SQLite) 时出现 IllegalStateException

什么是生命周期感知方式来实现重复的AsyncTask?

从另一个 Activity 类执行 Fragment 中的 AsyncTask 并更新其中的 UI

使用 recyclerview 和 Asynctask 设置 Viewpager