2016-12-10 31 views
0

我正在爲Android安裝比特幣儀表板。以下片段使用輸入的錢包地址在BTC中顯示餘額。當輸入地址時,它將添加到列表視圖。當選擇了列表視圖中的項目時,它會將edittext設置爲該地址。Android錯誤:IllegalStateException

它還沒有完成,但現在它引發錯誤消息,「適配器的內容已更改,但ListView沒有收到通知。請確保您的適配器的內容沒有從一個後臺線程,但只能從UI線程中獲得。「

我目前有兩個示例地址用於測試。如果我選擇一個然後再選擇第一個等,它工作正常。當我選擇一個時出現錯誤,按下按鈕,然後選擇另一個。

public class WalletFragment extends Fragment { 

    ArrayList<String> savedWallets; 
    ArrayAdapter<String> listAdapter; 
    String newWalletAddress, jsonString, address, balance; 
    JSONObject jsonObj, data; 
    Double balanceDouble; 
    DecimalFormat df = new DecimalFormat("#.####"); 
    private WalletListener listener; 

    public interface WalletListener { 
     void onCreateWallet(String newWalletAddress); 
    } 

    public WalletFragment() { 
     // Required empty public constructor 
    } 

    public static WalletFragment newInstance(ArrayList<String> wallets) { 
     WalletFragment fragment = new WalletFragment(); 
     Bundle args = new Bundle(); 
     args.putStringArrayList("savedWallets", wallets); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    public static WalletFragment newInstance(ArrayList<String> wallets, String json) { 
     WalletFragment fragment = new WalletFragment(); 
     Bundle args = new Bundle(); 
     args.putStringArrayList("savedWallets", wallets); 
     args.putString("jsonString", json); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     if (context instanceof WalletListener) { 
      listener = (WalletListener) context; 
     } 
     else { 
      throw new ClassCastException(context.toString() 
        + " must implement MyListFragment.OnItemSelectedListener"); 
     } 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     listener = null; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.fragment_wallet, container, false); 
     ListView lv = (ListView) v.findViewById(R.id.walletListView); 
     df.setRoundingMode(RoundingMode.CEILING); 

     final EditText walletAddressEditText = (EditText) v.findViewById(R.id.walletAddressEditText); 
     TextView addressTV = (TextView) v.findViewById(R.id.walletAddresstextView); 
     TextView balanceTV = (TextView) v.findViewById(R.id.walletBalanceTextView); 

     savedWallets = getArguments().getStringArrayList("savedWallets"); 

     if (savedWallets == null) { 
      savedWallets = new ArrayList<>(); 
     } 
     savedWallets.add("198aMn6ZYAczwrE5NvNTUMyJ5qkfy4g3Hi"); 
     savedWallets.add("1L8meqhMTRpxasdGt8DHSJfscxgHHzvPgk"); 
     // TODO remove test addresses 

     jsonString = getArguments().getString("jsonString"); 

     if (jsonString != null) { 
      try { 
       jsonString = getArguments().getString("jsonString"); 
       jsonObj = new JSONObject(jsonString); 
       data = new JSONObject(jsonObj.getString("data")); 
       balance = data.getString("balance"); 
       balanceDouble = Double.parseDouble(balance); 
       address = data.getString("address"); 

       String walletAddressText = getResources().getString(R.string.wallet_address, address); 
       addressTV.setText(walletAddressText); 

       String walletBalanceText = getResources().getString(R.string.wallet_balance, df.format(balanceDouble)); 
       balanceTV.setText(walletBalanceText); 

       // TODO add viewing for other wallet data at some point 

      } catch (Exception e) { 
       Log.d("TickerException", e.toString()); 
      } 
     } 

     listAdapter = new ArrayAdapter<>(getActivity(), R.layout.main_list_rows, savedWallets); 
     lv.setAdapter(listAdapter); 
     lv.setOnItemClickListener(new AdapterView.OnItemClickListener() 
     { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
      { 
       String address = savedWallets.get(position); 
       Log.d("wallet", "Selected: " + address); 
       walletAddressEditText.setText(address); 
      } 
     }); 

     Button button = (Button) v.findViewById(R.id.createWalletButton); 
     View.OnClickListener ocl = new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       newWalletAddress = walletAddressEditText.getText().toString(); 
       if (walletAddressEntryStructuralValidation(newWalletAddress)) { 
        if (newWalletAddress != null) { 
         listener.onCreateWallet(newWalletAddress); 
        } 
        else { 
         Toast.makeText(getActivity(), "newWalletAddress is null", Toast.LENGTH_SHORT).show(); 
        } 
       } 
       else { 
        Toast.makeText(getActivity(), "Please enter a valid wallet address (length is currently " + newWalletAddress.length() + ").", Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }; 
     // TODO check if wallet is already on list 
     button.setOnClickListener(ocl); 

     return v; 
    } 

    public boolean walletAddressEntryStructuralValidation(String address) { 
     return ((address.length() > 25) && 
       (address.length() < 36) && (
       (address.substring(0,1).equals("1") || 
         (address.substring(0,1).equals("3"))))); 
    } 
    // Wallet addresses are 26-35 alphanumeric characters and begin with 1 or 3 

} 

我相信這是所有相關的代碼,但我將密切關注這個線程如果有人需要請求額外的來源。

回答

1

該消息意味着適配器的內容(您在getItem中看到的項的順序)發生了變化,但notifyDataSetChanged或類似的函數未被調用。當更改適配器內容中的項目(在本例中爲savedWallets數組列表)時,您必須調用其中一個函數。

注意:如果您要一次添加多個對象,則只需在添加/刪除所有對象後再調用它。如果你正在改變一個對象而不添加/刪除它,你不需要調用它,但調用它可能是重繪的最簡單方法。

+0

我無意改變數據集的內容,但我正在將新的錢包地址條目添加到列表中;也許這開始工作不知道。我是否正確理解錯誤是由於錢包地址字符串的ArrayList發生了變化而引發的,或者它可能是別的嗎? – hunsbct

+0

是的,錯誤被拋出,因爲savedWallets數組不再包含相同順序的相同項目。你可以添加東西到這個列表中,但是你必須在下一次重繪之前調用notifyDataSetChanged。 –

+0

我想我已經解決了這個問題,但還有一個問題:我應該在哪裏調用這個方法?我相信它應該放在發佈片段的onCreateView中,但是你有更具體的位置嗎? – hunsbct

相關問題