天天看點

Android Fragment 切換多個界面 重疊問題 隐藏問題

      接上一篇的博文: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());
				}
			}
		}
	}