马上...我是Android新手,所以我提前道歉。 我有一个活动(放置片段(扩展了一个片段活动。 放置活动有一个片段寻呼适配器。 FragmentPagerAdapter 使用扩展 Fragment 的 PlacementFragment。 在 PlacementFragment 中,我有一个 ListViewAdapter。 在放置活动中,我希望在操作栏中有一个自定义搜索框,当完成输入条件时,它将运行AsyncTask(SearchActivity(来查询外部数据库。 一旦AsyncTask完成,我想刷新(活动,片段,PageViewAdapter或ListViewAdapter(?? 不知道该怎么做。 我已经尝试了 adapter.notifyDataSetChanged(( 用于 ListView 和 Pager。 我试图替换片段,开始新的意图,清除列表并添加新项目。
调试时,我可以看到我的列表项具有来自 AsyncTask 的更新值,但我无法更新列表。
安置活动
package com.operatorschool.ats;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import java.lang.reflect.Method;
/**
* Created by MDK177 on 6/12/2014.
*/
public class PlacementActivity extends FragmentActivity implements ActionBar.TabListener {
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
ViewPager mViewPager;
private TextView tvMessage;
public static String userData;
public static String[] Courses = {"Heavy", "Crane", "Truck", "Drilling", "RigSig"};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(com.operatorschool.ats.R.layout.activity_viewpager);
Intent inPlacement = getIntent();
userData = inPlacement.getStringExtra("data");
tvMessage = findViewById(R.id.tvMessage);
final ActionBar actionBar = getActionBar();
// Create the adapter that will return a fragment for each of the primary sections
// of the app.
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
// Specify that the Home/Up button should not be enabled, since there is no hierarchical
// parent.
actionBar.setHomeButtonEnabled(true);
getActionBar().setDisplayHomeAsUpEnabled(true);
// add the custom view to the action bar
actionBar.setCustomView(R.layout.search_layout);
EditText search = (EditText) actionBar.getCustomView().findViewById(
R.id.searchBox);
search.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
//Toast.makeText(PlacementActivity.this, "Search triggered",
// Toast.LENGTH_LONG).show();
new SearchActivity(PlacementActivity.this, tvMessage, "placement",
"trn_Job_Postings", "zip", "=", v.getText().toString()).execute("trn_Job_Postings", "zip", "=", v.getText().toString());
//Intent intent = getIntent();
// Finish the activity
//finish();
// Restart the activity
//startActivity(intent);
mAppSectionsPagerAdapter.notifyDataSetChanged();
mViewPager.setAdapter(mAppSectionsPagerAdapter);
return false;
}
});
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM
| ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP);
// Specify that we will be displaying tabs in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up the ViewPager, attaching the adapter and setting up a listener for when the
// user swipes between sections.
mViewPager = findViewById(com.operatorschool.ats.R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.addOnPageChangeListener (new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// When swiping between different app sections, select the corresponding tab.
// We can also use ActionBar.Tab#select() to do this if we have a reference to the
// Tab.
actionBar.setSelectedNavigationItem(position);
}
});
// Sliding Tab Layout Attempt
//mSlidingTabLayout = (SlidingTabLayout)view.findViewById(R.id.pager_title_strip);
//mSlidingTabLayout.setViewPager(mViewPager);
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by the adapter.
// Also specify this Activity object, which implements the TabListener interface, as the
// listener for when this tab is selected.
actionBar.addTab(
actionBar.newTab()
.setText(mAppSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
forceTabs();
}
public void forceTabs() {
try {
final ActionBar actionBar = getActionBar();
final Method setHasEmbeddedTabsMethod = actionBar.getClass()
.getDeclaredMethod("setHasEmbeddedTabs", boolean.class);
setHasEmbeddedTabsMethod.setAccessible(true);
setHasEmbeddedTabsMethod.invoke(actionBar, false);
}
catch(final Exception e) {
// Handle issues as needed: log, warn user, fallback etc
// This error is safe to ignore, standard tabs will appear.
}
}
public String getUserData(){
return userData;
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to one of the primary
* sections of the app.
*/
public class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
Fragment fragment = new PlacementFragment();
Bundle args = new Bundle();
if(userData != null && !userData.isEmpty()) {
args.putInt(PlacementFragment.ARG_COURSE_NAME, i);
args.putString(PlacementFragment.ARG_COURSE_DATA, userData);
fragment.setArguments(args);
}
return fragment;
}
@Override
public int getItemPosition(Object object) {
if (object instanceof PlacementFragment) {
//return POSITION_UNCHANGED; // don't force a reload
} else {
// POSITION_NONE means something like: this fragment is no longer valid
// triggering the ViewPager to re-build the instance of this fragment.
//return POSITION_NONE;
}
return 0;
}
@Override
public int getCount() {
return Courses.length;
}
@Override
public CharSequence getPageTitle(int position) {
return Courses[position];
}
}
/**
* A fragment that launches other parts of the demo application.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.menu_search, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.action_search:
case com.operatorschool.ats.R.id.miDownloads:
Intent inDownloads = new Intent(getApplicationContext(), DownloadListActivity.class);
startActivity(inDownloads);
break;
case com.operatorschool.ats.R.id.miStartDates:
Intent inStartDates = new Intent(getApplicationContext(), StartDatesActivity.class);
inStartDates.putExtra("data", userData);
startActivity(inStartDates);
break;
case com.operatorschool.ats.R.id.miApplication:
Intent inApplication = new Intent(getApplicationContext(), ApplicationActivity.class);
inApplication.putExtra("data", userData);
startActivity(inApplication);
break;
case com.operatorschool.ats.R.id.miContacts:
Intent inCounselor = new Intent(getApplicationContext(), ContactsActivity.class);
inCounselor.putExtra("data", userData);
startActivity(inCounselor);
break;
case com.operatorschool.ats.R.id.miHome:
Intent inHome = new Intent(getApplicationContext(), HomeActivity.class);
inHome.putExtra("data", userData);
startActivity(inHome);
break;
case com.operatorschool.ats.R.id.miTranscript:
Intent inTranscript = new Intent(getApplicationContext(), TranscriptActivity.class);
inTranscript.putExtra("data", userData);
startActivity(inTranscript);
break;
case com.operatorschool.ats.R.id.miCredentials:
Intent inCredentials = new Intent(getApplicationContext(), CredentialsListActivity.class);
inCredentials.putExtra("data", userData);
startActivity(inCredentials);
break;
case com.operatorschool.ats.R.id.miPlacement:
Intent inPlacement = new Intent(getApplicationContext(), PlacementActivity.class);
inPlacement.putExtra("data", userData);
startActivity(inPlacement);
break;
}
return super.onOptionsItemSelected(item);
}
}
放置片段
package com.operatorschool.ats;
import android.app.Activity;
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.AdapterView;
import android.widget.ListView;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class PlacementFragment extends Fragment implements AdapterView.OnItemClickListener {
public static String ARG_COURSE_NAME = "course_name";
public static String ARG_COURSE_DATA = "course_data";
public static String[] Courses = {"Heavy", "Crane", "Truck", "Drilling", "RigSig"};
int image_id;
ListView listView;
List<PlacementRowItem> rowItems;
PlacementListViewAdapter adapter;
private JSONObject userData;
private JSONObject postingData;
private JSONObject coursePostingsData;
private View rootView;
private Bundle args;
private Activity parentActivity;
//private ViewPager mViewPager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(com.operatorschool.ats.R.layout.activity_viewpager_list, container, false);
args = getArguments();
//PlacementActivity pActivity = (PlacementActivity) getActivity();
//String plData = sdActivity.getUserData();
parentActivity = ((PlacementActivity)getActivity());
//parentActivity.recreate();
//listView = rootView.findViewById(R.id.lvItems);
//listView.setAdapter(null);
///mViewPager = parentActivity.findViewById(com.operatorschool.ats.R.id.pager);
//mViewPager.setAdapter(mAppSectionsPagerAdapter);
try{
userData = new JSONObject(args.getString(ARG_COURSE_DATA));
postingData = userData.getJSONObject("Postings");
if(postingData.has(Courses[args.getInt(ARG_COURSE_NAME)])) {
coursePostingsData = postingData.getJSONObject(Courses[args.getInt(ARG_COURSE_NAME)]);
getItems();
}
} catch (JSONException e) {
e.printStackTrace();
//Log.d("POSTINGS", e.toString());
}
return rootView;
}
@Override
public void onResume() {
super.onResume();
//if(rowItems != null){
// rowItems.clear();
// adapter.notifyDataSetChanged();
//}
//getItems();
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
private void getItems(){
rowItems = new ArrayList<PlacementRowItem>();
rowItems.clear();
for (Iterator<String> iterator = coursePostingsData.keys(); iterator.hasNext(); ) {
String sd = iterator.next();
try {
JSONObject postingInfo = coursePostingsData.getJSONObject(sd);
String company = postingInfo.getString("company");
String position = postingInfo.getString("other");
String location = "";
String website = "";
String email = "";
String telephone = "";
if(postingInfo.has("address")) {
if (postingInfo.getString("address") != "null") {
location = location + postingInfo.getString("address") + ", ";
}
}
location = location + postingInfo.getString("city") + " " + postingInfo.getString("state") + ", " + postingInfo.getString("zip");
if(postingInfo.has("website")) {
website = postingInfo.getString("website");
}
if(postingInfo.has("email")) {
email = postingInfo.getString("email");
}
if(postingInfo.has("telephone")) {
telephone = postingInfo.getString("telephone");
}
if (Courses[args.getInt(ARG_COURSE_NAME)] == "Heavy") {
image_id = com.operatorschool.ats.R.drawable.ic_pl_pin_heavy;
} else if (Courses[args.getInt(ARG_COURSE_NAME)] == "Crane") {
image_id = com.operatorschool.ats.R.drawable.ic_pl_pin_crane;
} else if (Courses[args.getInt(ARG_COURSE_NAME)] == "Drilling") {
image_id = com.operatorschool.ats.R.drawable.ic_pl_pin_drilling;
} else if (Courses[args.getInt(ARG_COURSE_NAME)] == "RigSig") {
image_id = com.operatorschool.ats.R.drawable.ic_pl_pin_rigsig;
} else {
image_id = com.operatorschool.ats.R.drawable.ic_pl_pin_truck;
}
//String posting, String location, int image_id, String link, String email, String telephone
PlacementRowItem item = new PlacementRowItem(company, position, location, image_id, website, email, telephone);
rowItems.add(item);
} catch (JSONException e) {
e.printStackTrace();
//Log.d("POSTINGS", e.toString());
}
}
listView = rootView.findViewById(R.id.lvItems);
adapter = new PlacementListViewAdapter(getActivity(), com.operatorschool.ats.R.layout.placement_list_item, rowItems);
//adapter.clear();
adapter.notifyDataSetInvalidated();
listView.invalidate();
adapter.addAll(rowItems);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
Activity p = getActivity();
listView.setOnItemClickListener(this);
}
}
搜索活动
package com.operatorschool.ats;
/**
* Created by MDK177 on 5/14/2014.
*/
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import javax.net.ssl.HttpsURLConnection;
import static com.operatorschool.ats.Utilities.toTitleCase;
public class SearchActivity extends AsyncTask<String, Void, String> {
private Context context;
private ProgressDialog pDialog;
private JSONObject json;
private TextView tvMessage;
private String ActivitySelected;
private String db_table, db_field, db_criteria, db_logical_operator;
private FragmentActivity mainActivity;
public static String[] Courses = {"Heavy", "Crane", "Truck", "Drilling", "RigSig"};
public SearchActivity(Context context, TextView strMessage, String activity, String db_table,
String db_field, String db_logical_operator, String db_criteria){
this.context = context;
this.tvMessage = strMessage;
this.ActivitySelected = toTitleCase(activity);
this.db_table = db_table;
this.db_field = db_field;
this.db_criteria = db_criteria;
this.db_logical_operator = db_logical_operator;
mainActivity = (FragmentActivity) context;
}
protected void onPreExecute(){
super.onPreExecute();
pDialog = new ProgressDialog(this.context);
pDialog.setMessage("Searching " + this.ActivitySelected + "... please wait!");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected String doInBackground(String... args){
try{
JSONObject postDataParams = new JSONObject();
postDataParams.put("tbl", args[0]);
postDataParams.put("fld", args[1]);
postDataParams.put("log", args[2]);
postDataParams.put("cri", args[3]);
//Log.d("params",postDataParams.toString());
try {
URL url = new URL("{LEFT OUT ON PURPOSE}");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(15000);
urlConnection.setConnectTimeout(15000);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
int responseCode = urlConnection.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
in.close();
return sb.toString();
}else {
return "";
}
} catch (Exception e) {
e.printStackTrace();
}
}catch (Exception e){
//Log.d("Exception:", e.getMessage());
return new String("Exception: " + e.getMessage());
}
return "";
}
public String getPostDataString(JSONObject params) throws Exception {
StringBuilder result = new StringBuilder();
boolean first = true;
Iterator<String> itr = params.keys();
while(itr.hasNext()){
String key= itr.next();
Object value = params.get(key);
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(key, "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(value.toString(), "UTF-8"));
}
return result.toString();
}
protected void onPostExecute(String data){
String TAG_SUCCESS = "success";
String TAG_MESSAGE = "message";
String TAG_DATA = "data";
try {
json = new JSONObject(data);
int success = json.getInt(TAG_SUCCESS);
String message = json.getString(TAG_MESSAGE);
String user_info = json.getString(TAG_DATA);
if(success == 1){
if(this.ActivitySelected.equals("Placement")) {
// TODO change fragment
//Intent inApp = new Intent(this.context, ApplicationFragment.class);
//inApp.putExtra("data", user_info);
//inApp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//this.context.startActivity(inApp);
//Activity activity = (AppCompatActivity ) context;
/*FragmentManager fm = mainActivity.getSupportFragmentManager();
Fragment f = new PlacementFragment();
Bundle arguments = new Bundle();
arguments.putInt( "course_name" , 0);
arguments.putString( "course_data" , user_info);
f.setArguments(arguments);
FragmentTransaction transaction = fm.beginTransaction();
transaction.setTransition(transaction.TRANSIT_FRAGMENT_OPEN);
LinearLayout contentView = mainActivity.findViewById(R.id.llFragment);
transaction.replace(contentView.getId(), f);
transaction.addToBackStack(null);
transaction.commit();
*/
//PlacementActivity.userData = user_info;
}
}else{
this.tvMessage.setText(message);
this.tvMessage.setVisibility(View.VISIBLE);
Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
toast.show();
}
pDialog.dismiss();
}catch (Exception e){
//Log.d("onPostExecuteError", e.toString());
//this.tvMessage.setText("There was an error logging in. Please try again!");
//this.tvMessage.setVisibility(View.VISIBLE);
Toast toast = Toast.makeText(context, "There was an error with your request. Please try again!", Toast.LENGTH_LONG);
toast.show();
pDialog.dismiss();
}
}
}
因此,ViewPager
预先创建当前视图两侧的视图。
不幸的是,setOffscreenPageLimit
最小值为 1(默认值(。
这意味着当您在当前页面或旁边的页面上时,永远不会调用当前旁边的任何片段的onCreateView
,以便它随后对列表视图的更新数据执行某些操作。
您基本上具有带有 viewpager 缓存页面的嵌套适配器,因此您需要告诉内部适配器它的内容已更改,外部适配器它的内容已更改。
我通过通知您的情况中 ViewPager 适配器已更改mAppSectionsPagerAdapter.notifyDataSetChanged();
来解决此问题。
更新:我使用查看页上的addOnPageChangeListener
通知视图寻呼机适配器的页面已更改,当您切换到包含需要更新内容的页面时会调用该页面,但是您可以在其他页面上的数据需要更新时立即执行此操作,但这可能会导致重新绘制当前页面。
例如
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// Pages 1 and 2 have dynamic content, page 0 has static content
if (position == 1 || position == 2)
{
mAppSectionsPagerAdapter.notifyDataSetChanged();
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Code goes here
}
@Override
public void onPageScrollStateChanged(int state) {
// Code goes here
}
});
这会让视图寻呼机在当前页面旁边重新创建所需的页面。
请注意,您可以进行一些优化,以确保仅在绝对必要时通知视图寻呼机适配器进行更改,但就我而言,大多数情况下缓存的 viewpager 页面需要更新。
然后,我覆盖视图页机适配器中的getItemPosition
AppSectionsPagerAdapter
在您的情况下,因为这会为每个页面调用,并将片段作为对象传递。
调用更新函数,例如
@Override
public int getItemPosition(Object object) {
if (object instanceof PlacementFragment) {
PlacementFragment f = (PlacementFragment) object;
if (f != null) {
f.update();
// Or in your case the below should work
//f.adapter.notifyDataSetChanged();
// this equates to equates to
//`PlacementFragment.adapter.notifyDataSetChanged();`
// Notify the fragment's listview it's data is changed.
}
}
return super.getItemPosition(object);
}
同样,这可以优化为仅在需要时更新内部适配器。