我一直在寻找我的问题的答案,但我似乎没有得到任何答案,尽管我遵循了多少教程,我经历了多少问题,以及我试图做多少我想做的事情。基本上,我偶然发现了一些好的技巧,但仍然无法做到想要的。
问题
我正在创建一个将使用片段(与选项卡一起)的 Android 应用程序。在这些片段中,我有与应用程序相关的重要信息,例如文本框和按钮。但是,我想做一些非常简单的事情,那就是在我回到它时更新我的一个片段(想象我滑回一个片段,并用相关信息更新它)。信息存储在哪里?在 node.js 服务器上,我每次需要信息时都会调用它。因此,我创建了以下结构。
结构
首先,我开始创建我的活动。
public class CentralActivity extends FragmentActivity {
CentralPagerAdapter mCentralActivity;
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_central);
tabHandler();
}
public void tabHandler() {
mCentralActivity = new CentralPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.CentralPager);
mViewPager.setAdapter(mCentralActivity);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
getActionBar().setSelectedNavigationItem(position);
}
});
//Action Bar Stuff
}
}
话虽如此,我需要我的 CentralPagerAdapter,我创建如下。
public class CentralPagerAdapter extends FragmentStatePagerAdapter {
private int nSwipes = 3;
public CentralPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
Fragment fragment = new CentralFragment();
Bundle args = new Bundle();
args.putInt(CentralFragment.ARG_OBJECT, i + 1);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
return nSwipes;
}
}
现在,我的片段,它只是一个包含我所有视图和选项等的类。
public class CentralFragment extends Fragment {
public static final String ARG_OBJECT = "object";
private View rootView;
private RESTFunction currentFunction;
//Has the info I want
private ArrayList<Integer> tickets = new ArrayList<Integer>();
@SuppressLint("HandlerLeak")
private Handler threadConnectionHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (currentFunction) {
case GET_CLIENT_TICKETS:
handleGetTickets(msg);
break;
case BUY_CLIENT_TICKETS:
break;
default:
break;
}
}
};
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
final Bundle args = getArguments();
handleFragments(inflater, container);
getTicketInfo(null);
return rootView;
}
private void handleFragments(LayoutInflater inflater, ViewGroup container) {
Bundle args = getArguments();
if (args.getInt(ARG_OBJECT) == 1) {
rootView = inflater.inflate(R.layout.fragment_show_tickets,
container, false);
showTicketsHandler();
} else if (args.getInt(ARG_OBJECT) == 2) {
rootView = inflater.inflate(R.layout.fragment_buy_tickets,
container, false);
buyTicketsHandler();
} else {
rootView = inflater.inflate(R.layout.fragment_history_tickets,
container, false);
}
}
public void showTicketsHandler() {
//Get stuff from the tickets array that the REST call will handle
//And set them to boxes or radio buttons
}
public void buyTicketsHandler() {
//Get stuff from the tickets array that the REST call will handle
//And set them to boxes or radio buttons
//As well as button click listeners
}
public void getTicketInfo(ProgressDialog progDialog) {
//Connect to the thread to get the information
//In this case, I have no parameters
ConnectionThread dataThread = new ConnectionThread("myLink", Method.GET, null, threadConnectionHandler, progDialog);
dataThread.start();
}
//Get stuff from the resulting JSON and store it in the tickets ArrayList
private void handleGetTickets(Message msg) {
JSONObject ticketListing = (JSONObject) msg.obj;
try {
tickets.add(ticketListing.getInt("t1"));
tickets.add(ticketListing.getInt("t2"));
tickets.add(ticketListing.getInt("t3"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
然后,我有我的线程..
public class ConnectionThread extends Thread {
private ConnectionRunnable runConnection;
private Handler mHandler;
private ProgressDialog progDialog;
public ConnectionThread(String link, Method method, ArrayList<NameValuePair> payload, Handler handler, ProgressDialog progDialog) {
runConnection = new ConnectionRunnable(link, method.toString(), payload);
mHandler = handler;
this.progDialog = progDialog;
}
@Override
public void run() {
runConnection.run();
threadMsg();
if(progDialog != null)
progDialog.dismiss();
}
public JSONObject getJSON() {
return runConnection.getResultObject();
}
private void threadMsg() {
Message msgObj = mHandler.obtainMessage();
msgObj.obj = getJSON();
mHandler.sendMessage(msgObj);
}
}
ConnectionRunnable 是我运行 HttpURLConnection 的地方。
那么我需要什么?
基本上,我要做的是在加载所有视图并更新它们之前从 ConnectionThread 获取票证信息。另外,我希望能够来回滑动,并在我滑动屏幕时更新我在阵列上的信息(如果我转到第二个屏幕,票会更新,如果我回到第一个屏幕,他们将重新更新)。所以基本上,每次我滑动时都调用 ConnectionThread。如果那是可能的,那就是。
我尝试了什么?
我已经尝试了几件事,但实际上都没有帮助..
- 在fragment的onCreateView方法上使用ProgressDialogs来停止UI Thread(没用,因为它在处理所有事情之前返回了rootView);
- 使 UI 线程休眠 1 秒(我不知道为什么,它会阻塞所有线程);
- 覆盖Adapter的instantiateMethod(),虽然我觉得我没做对;
- 覆盖Adapter的saveState(),以防止其保存状态,进而获取新的ticket信息;
- 给 Fragments 标签以更新它们在 Adapter 上的 rootViews,但无济于事;
- 在活动中获取信息,每次购买(第二个片段)时,重新启动整个活动以获取门票,我认为这是一个非常非常糟糕的解决方案。
我已经阅读了几篇文章,但我仍然找不到我的答案。这真的很令人沮丧。然而,因为它是如此简单,所以我必须在不同的线程上运行 HTTP 调用这一事实延迟了整个 UI 更新过程。
我还阅读了 AsyncTask 的方法。但是,我觉得 Threads 和 AsyncTasks 最终都是一样的。
现在要做什么?
嗯,这就是我希望找到的。因为它最终会很烦人。
可能的原因
是不是因为我将所有类都分成了散布文件,因此使我的工作变得困难?
谢谢你的时间,伙计们,希望我们能找到解决方案或其他东西。
编辑
所以基本上,在阅读了 4 个小时的文档和教程之后,我发现我需要的是 setOffscreenPageLimit( int
)。但是,它不能设置为 0,所以我将不得不使用 setOnPageChangeListener。现在,要弄清楚如何刷新片段,我会像新的一样。
好的,它完美运行!基本上,我这样做了:
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
((CentralFragment)((CentralPagerAdapter) mViewPager.getAdapter()).instantiateItem(mViewPager, position)).refresh();
getActionBar().setSelectedNavigationItem(position);
}
});
我的 .refresh 在哪里:
public void refresh() {
Bundle args = getArguments();
if (args.getInt(ARG_OBJECT) == 0) {
getTicketInfo(0);
} else if (args.getInt(ARG_OBJECT) == 1) {
getTicketInfo(1);
buyTicketsHandler();
} else {
//To Handle Later
}
}
就像在访问之前刷新页面一样简单。为什么我以前不记得这个..?所以,这里是那些有需要的人的参考!