接上一篇的博文:Android fragment 切換加載資料卡頓問題,想到的辦法就是把切換之前的fragmenthide隐藏起來,就可以解決卡頓的問題,不用重新new一個fragment。由于左側懸浮菜單有差不多10多個菜單,如果每一個菜單切換的時候,都要隐藏其餘所有的菜單,那就會導緻代碼十分的臃腫,以前隐藏的代碼是這樣的:
/*if (!openPositionFragment.isAdded()) { // 先判斷是否被add過
transaction.hide(priceFragment)
.add(R.id.fragment_container, openPositionFragment)
.commit(); // 隐藏目前的fragment,add下一個到Activity中
titleView.setText(openPositionFragment.getFragmentTitle());
} else {
transaction.hide(priceFragment).show(openPositionFragment)
.commit(); // 隐藏目前的fragment,顯示下一個
titleView.setText(openPositionFragment.getFragmentTitle());
}*/
每一個菜單按鈕下的點選事件,都要寫一段這樣的代碼,而且局限是隻能隐藏一個,導緻切換的時候有重疊問題,無法正确顯示。
解決的方案是:
先隐藏所有的fragment,然後進入點選事件,如果該fragment已經執行個體化,那就show就好,如果沒有還未執行個體化,那就先new一個,然後show,最後一定記得commit,我就是由于沒寫這句代碼導緻空指針異常。還有一點注意的是必須先執行個體化你第一個進入的fragment。修改之後的代碼如下:
private void initOpenMenuItem(View popupWindow_view) {
DrawableCenterTextView menu_price = (DrawableCenterTextView) popupWindow_view
.findViewById(R.id.menu_price);
menu_price.setOnClickListener(new OnClickListener() {
FragmentTransaction transaction;
@Override
public void onClick(View v) {
progressDialog.show();
transaction = manager.beginTransaction();
hideFragments(transaction);
/*
* qiulinhe:2015年7月21日10:54:51 解決切換卡頓的問題
*/
if (priceFragment == null) {
// 如果MessageFragment為空,則建立一個并添加到界面上
priceFragment = new PriceFragment();
transaction.add(R.id.fragment_container, priceFragment);
titleView.setText(priceFragment.getFragmentTitle());
} else {
// 如果MessageFragment不為空,則直接将它顯示出來
transaction.show(priceFragment);
titleView.setText(priceFragment.getFragmentTitle());
}
transaction.commit();
popupWindow.dismiss();
progressDialog.dismiss();
}
});
}
/**
* 将所有的Fragment都置為隐藏狀态。
*
* @param transaction
* 用于對Fragment執行操作的事務
*/
private void hideFragments(FragmentTransaction transaction) {
if (priceFragment != null) {
transaction.hide(priceFragment);
}
if (openPositionFragment != null) {
transaction.hide(openPositionFragment);
}
if (closeHisFragment != null) {
transaction.hide(closeHisFragment);
}
if (orderHisFragment != null) {
transaction.hide(orderHisFragment);
}
}
這樣就可以解決fragment切換重疊,無法正常顯示的問題。不過這裡提一個問題,就是hide方法執行之後,被隐藏的fragment,如果背景在擷取資料,重新整理界面,是否會導緻資料太多,程式崩潰的問題?
經過背景列印的時候,的确顯示的目前fragment更新資料,但那些隐藏的fragment仍然在背景運作,這勢必導緻記憶體越來越被占用。
如何解決?
2015年8月14日10:23:44:今天終于找到了解決方案:
之前監聽資料變化,是根據資料變化的監聽器變化,發送了一個事件,fragment接收到了之後,重新綁定資料源,加載資料,更新listview清單項。我的處理方法很笨:定義了一個map,存放每個行的資料,當資料以來,我就map.removeall(map),然後重新加載整個清單項,一開始資料少,更新慢,不會影響長按操作,後期測試的時候,資料變化很快,就導緻了長按按鈕無法正常使用的問題。
同僚提供了一個很好的解決方案就是:判斷資料源裡的資料和現在展示出來的清單資料,哪些是發生了變化,這樣隻更新變化的幾個字段,就不會導緻重新加載之後,資料重新整理太快,導緻長按無法使用。
@Override
public void onTradeChanged(Long ticket) {
isHidden();
// 如果交易發生變化,則從新獲取開倉數據
System.out.println(ticket + " ===== ");
if (!isHidden()) { //這個就是fragment就是判斷目前fragment是否隐藏,如果已經隐藏了,就不在背景更新資料,不接受更新
onTradeDataChange(ticket);
}
}
=========================更新時間2016年2月26日11:00:25:增加如何更新map中的部分資料,避免先全部删除map的資料,代碼如下:
//
private void onTradeDataChange() {
updateTableData();
fireTableDataChange();
}
public void fireTableDataChange() {
getHandler().post(new Runnable() {
@Override
public void run() {
// tableAdapter.notifyDataSetInvalidated();
if (tableAdapter != null) {
tableAdapter.notifyDataSetChanged();
}
}
});
}
/**
*
* @Title:?updateTableData
* @Description:?資料發生變化
* @param?
* @return?void
* @throws??
*/
private void updateTableData() {
dataMap.clear();
TTrade[] tradeVec = getTradeVec();
for (TTrade trade : tradeVec) {
// if (!isExsitsTicketSplitno(trade)) {
HashMap<String, Object> rowData = addTradeNode(trade);
dataMap.add(rowData);
// } else {
// HashMap<String, Object> rowData = removeOpenPosition(trade);
// if (rowData != null) {
// dataMap.remove(rowData);
// }
// }
}
// 按照系統設定傳遞過來的資料進行排序
sortOrderHisByAll(oppsortInt);
}
/**
*
* @Title:?updateTableData
* @Description:?來資料時,更新
* @[email protected] instrumentName
* @return?void
* @throws??
*/
private void updateTableData(String instrumentName) {
for (HashMap<String, Object> rowData : dataMap) {
String instName = rowData.get(Instrument).toString();
if (instrumentName.equalsIgnoreCase(instName)) {
long ticket = Long.parseLong(rowData.get(Ticket).toString());
TTrade trade = APIDoc.getUserDocCaptain().getTrade(ticket);
if (trade != null) {
rowData.put(FloatPL, trade.get_floatPL());
rowData.put(MktPrice, trade.get_marketPrice());
}
}
}
}