2013-02-21 117 views
0

我碰到了牆頭,試圖解決這個問題一段時間。我不是一個有經驗的Android傢伙,所以它的解決方案可能非常簡單。如此說來,我有以下代碼:自定義適配器列表視圖Android

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
    setContentView(R.layout.adminusers); 
    super.onCreate(savedInstanceState); 

    // set user_type for Viewall 
    mUserType = 0; 

    lv_adminusersListContent.addFooterView(footerView); 
    mUsersAdapter = new AdminUsersAdapter(mUsersList, AdminUsers.this); 
    lv_adminusersListContent.setAdapter(mUsersAdapter); 

    getUsersList(); 

} 

private void getUsersList() { 

    if (UsefulFcts.isOnline(AdminUsers.this)) { 

     if (mThread != null && mThread.isAlive()) { 
      mThread.interrupt(); 
     } 

     mThread = new Thread() { 
      @Override 
      public void run() { 

       mHandler.post(new Runnable() { 

        @Override 
        public void run() { 
         pDialog = new ProgressDialog(AdminUsers.this); 
         pDialog.setMessage("Loading.. Please wait!"); 
         pDialog.setCancelable(false); 
         pDialog.show(); 
        } 
       }); 

       mUsersList.clear(); 
       mUsersList.addAll(mServiceManager.getUsersList(mUserType, 
         0 + "", AdminServiceManager.sHowManyToLoad)); 
       mArrayLength = mUsersList.size(); 

       Log.d("arrayLength", String.valueOf(mArrayLength)); 
       Log.d("total_results", 
         String.valueOf(ParserJSON.total_results)); 

       mHandler.post(new Runnable() { 

        @Override 
        public void run() { 

         // refresh listview 

         mUsersAdapter.notifyDataSetChanged(); 

         if (mArrayLength < ParserJSON.total_results) { 

          lv_adminusersListContent 
            .addFooterView(footerView); 

         } else if (mArrayLength >= ParserJSON.total_results) { 

          lv_adminusersListContent 
            .removeFooterView(footerView); 
         } 

         if (0 == mArrayLength) { 

          Toast.makeText(AdminUsers.this, 
            "No username found!", 
            Toast.LENGTH_SHORT).show(); 
         } 

         pDialog.dismiss(); 
        } 
       }); 
      } 
     }; 
     mThread.start(); 
    } else { 
     Toast.makeText(AdminUsers.this, "Internet connection required!", 
       Toast.LENGTH_LONG).show(); 
    } 
} 

@Override 
protected void linkUI() { 

    // begin load_more view 
    footerView = AdminUsers.this.getLayoutInflater().inflate(
      R.layout.loadmore, null); 

    btn_loadmore = (Button) footerView.findViewById(R.id.btn_loadmore); 
    // end load_more view 

    btn_adminusersViewall = (Button) findViewById(R.id.btn_adminusersViewall); 
    btn_adminusersAdmins = (Button) findViewById(R.id.btn_adminusersAdmins); 
    btn_adminusersClients = (Button) findViewById(R.id.btn_adminusersClients); 
    btn_adminusersDevs = (Button) findViewById(R.id.btn_adminusersDevs); 

    btn_adminAdd = (ImageButton) findViewById(R.id.btn_adminAdd); 

    lv_adminusersListContent = (ListView) findViewById(R.id.lv_adminusersListContent); 
} 

@Override 
protected void setAction() { 

    // begin Buttons UnderHeader 

    btn_adminusersViewall.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      UsefulFcts.setButtonClicked(btn_adminusersViewall, 
        btn_adminusersClients, btn_adminusersAdmins, 
        btn_adminusersDevs); 

      mUserType = 0; 

      mArrayLength = -1; 

      lv_adminusersListContent.removeFooterView(footerView); 

      getUsersList(); 

     } 
    }); 

    btn_adminusersClients.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      UsefulFcts.setButtonClicked(btn_adminusersClients, 
        btn_adminusersDevs, btn_adminusersAdmins, 
        btn_adminusersViewall); 

      mUserType = 1; 

      mArrayLength = -1; 

      // view.setVisibility(View.GONE); 

      getUsersList(); 
     } 
    }); 

    btn_adminusersDevs.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      UsefulFcts.setButtonClicked(btn_adminusersDevs, 
        btn_adminusersClients, btn_adminusersAdmins, 
        btn_adminusersViewall); 

      mUserType = 2; 

      mArrayLength = -1; 

      lv_adminusersListContent.removeFooterView(footerView); 

      getUsersList(); 
     } 
    }); 

    btn_adminusersAdmins.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      mUserType = 3; 

      mArrayLength = -1; 

      lv_adminusersListContent.removeFooterView(footerView); 

      getUsersList(); 
     } 
    }); 

    // end Buttons UnderHeader 

    btn_loadmore.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      mThread2 = new Thread() { 
       @Override 
       public void run() { 
        mHandler.post(new Runnable() { 

         @Override 
         public void run() { 

          progressBar = new ProgressDialog(
            AdminUsers.this); 
          progressBar 
            .setMessage("Loading more projects.. "); 
          progressBar.setCancelable(true); 
          progressBar.show(); 
         } 
        }); 

        mUsersList.addAll(mServiceManager.getUsersList(
          mUserType, String.valueOf(mArrayLength), 
          AdminServiceManager.sHowManyToLoad)); 

        mArrayLength = mUsersList.size(); 

        mHandler.post(new Runnable() { 

         @Override 
         public void run() { 

          mUsersAdapter.notifyDataSetChanged(); 

          if (mArrayLength >= ParserJSON.total_results) { 
           lv_adminusersListContent.removeFooterView(footerView); 
          } 
          progressBar.dismiss(); 
         } 
        }); 

       }; 
      }; 
      mThread2.start(); 
     } 
    }); 

注:我基本上具有從服務器取決於哪個按鈕(看上去像一個標籤)我壓制(mUserType = 0 /請求的內容列表視圖1/2/3)。我也使用Load More按鈕(footerView =帶按鈕的簡單佈局)。 一切似乎都工作得很好,但「打」與按鈕幾次(隨機數!)後死機,但下列情況除外拋出:

02-21 11:00:49.252: E/AndroidRuntime(11728): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131296461, class android.widget.ListView) with Adapter(class android.widget.HeaderViewListAdapter)] 

所以,我回頭看了看代碼,但無法看到任何「不在UI線程上」的listview通知。

1.問題是什麼?

2.就是用2個線程(mThread和mThread2)有必要,我也可以用相同的數據,作爲一個人的工作應該開始的另一端時(或者是不是?),我應該聲明他們是否靜態?

同時指出我未來可以使用的任何「良好實踐」技巧,或者我所做的「錯誤實踐」將非常感謝!

PS。在super()。onCreate()中調用linkUI()和setAction()。

回答

2

錯誤消息似乎可以理解的:你是從mThread修改適配器:

mUsersList.clear(); 
mUsersList.addAll(mServiceManager.getUsersList(mUserType, 
        0 + "", AdminServiceManager.sHowManyToLoad)); 

你可以嘗試這樣的事情:

  final List newUserList = mServiceManager.getUsersList(mUserType, 
        0 + "", AdminServiceManager.sHowManyToLoad); 

      mArrayLength = newUserList.size(); 

      Log.d("arrayLength", String.valueOf(mArrayLength)); 
      Log.d("total_results", 
        String.valueOf(ParserJSON.total_results)); 

      mHandler.post(new Runnable() { 

       @Override 
       public void run() { 
        mUsersList.clear(); 
        mUsersList.addAll(newUserList); 
        // refresh listview 

        mUsersAdapter.notifyDataSetChanged(); 
+0

我感謝你的快速和客觀的答案!我將讓這個線程活躍一段時間,對於我的第二個問題和好的/錯誤的實踐可能會有一些意見,然後我會接受你的答案! – DoruAdryan 2013-02-21 10:07:32

相關問題