使用 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
从 Fragment 内的 AsyncTask 重新启动 Loader (SQLite) 时出现 IllegalStateException