2017-02-15 61 views
-2

我得到了在一個listview中單擊的員工行,並將其傳回給MainActivity。然後我試圖將它傳遞給另一個適配器,它將更新其ListView並添加用戶點擊的那一行。我將該員工(可能不是最好的,因爲他們已經在數據庫中有一行)添加到數據庫。然後我創建一個遊標,抓住這一行並嘗試將遊標更改爲topAdapter(我試圖更新的listView適配器)。發送光標添加至另一個列表視圖

我在得到NullPointerException異常topAdapter.changeCursor(clcikedEmployee):

我不認爲創建一個新的TopListCursorAdapter會工作,我不希望創建一個新的,只是更新和新行添加到現有的列表是在裏面。我知道e不是null,因爲當我將它打印到控制檯時,我正確地獲取了點擊用戶的數據。只是無法將它傳遞給TopAdapter以將行添加到現有的列表視圖。

是否可以傳遞給TopFragment並從那裏更新TopListCursorAdapter以將新行添加到列表中?

主要活動

public class MainActivity extends FragmentActivity implements BottomListViewAdapter.BottomListClickListener { 
    private ProgressBar mProgressBar; 
    EmployeeDBHandler dbHandler; 
    private TopListCursorAdapter topAdapter; 
    private BottomListViewAdapter bottomAdapter; 
    private ArrayList<Employee> mEmployee; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mProgressBar = (ProgressBar) findViewById(R.id.progressBar); 
     dbHandler = new EmployeeDBHandler(getApplicationContext()); 
     mProgressBar.setVisibility(View.VISIBLE); 
     getXMLData(); 

     //GUI for seeing android SQLite Database in Chrome Dev Tools 
     Stetho.InitializerBuilder inBuilder = Stetho.newInitializerBuilder(this); 
     inBuilder.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this)); 
     Stetho.Initializer in = inBuilder.build(); 
     Stetho.initialize(in); 
    } 

    public void getXMLData() { 
     OkHttpClient client = getUnsafeOkHttpClient(); 
     Request request = new Request.Builder() 
       .url(getString(R.string.API_FULL_URL)) 
       .build(); 
     client.newCall(request).enqueue(new Callback() { 
      @Override 
      public void onFailure(Call call, IOException e) { 
       e.printStackTrace(); 
      } 

      @Override 
      public void onResponse(Call call, final Response response) throws IOException { 
       final String responseData = response.body().string(); 
       final InputStream stream = new ByteArrayInputStream(responseData.getBytes()); 
       final XMLPullParserHandler parserHandler = new XMLPullParserHandler(); 
       final ArrayList<Employee> employees = (ArrayList<Employee>) parserHandler.parse(stream); 

       for (Employee e : employees) { 
        dbHandler.addEmployee(e); 
       } 

       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         mProgressBar.setVisibility(View.GONE); 
         displayTopList(); 
         displayBottomList(); 
        } 
       }); 
      } 
     }); 
    } 

    public void displayTopList() { 
     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.topFragment, new TopFragment()); 
     fragmentTransaction.commit(); 
    } 

    public void displayBottomList() { 
     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.bottomFragment, new BottomFragment()); 
     fragmentTransaction.commit(); 
    } 



@Override 
public void onBottomListClick(Employee e) { 
    dbHandler.addEmployee(e); 
    Log.i("EMPLOYEE", e.toString()); 
    TopFragment topFragment = (TopFragment) getSupportFragmentManager().findFragmentById(R.id.topFragment); 
    SQLiteDatabase db = dbHandler.getWritableDatabase(); 
    final Cursor clickedEmployee = db.rawQuery("SELECT * FROM " + "employees" + " WHERE " + 
      "Employee_number" + "=" + e.getEmployee_number(), null); 
    // change the adapter's Cursor 
    topFragment.update(clickedEmployee); 
} 

}

TopFragment

public class TopFragment extends Fragment { 
    public Cursor mTopCursor; 
    EmployeeDBHandler dbHandler; 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_top_list, container, false); 
     String table = "employees"; 
     int mStartingEmployeeID = 3500075; 
     dbHandler = new EmployeeDBHandler(getContext()); 
     SQLiteDatabase db = dbHandler.getWritableDatabase(); 
     mTopCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null); 
     ListView mTopListView = (ListView) view.findViewById(R.id.mTopList); 
     TopListCursorAdapter topAdapter = new TopListCursorAdapter(getContext(), mTopCursor); 
     mTopListView.setAdapter(topAdapter); 

     return view; 
    } 

public void update(Cursor cursor) { 
     MergeCursor mergeCursor = new MergeCursor(new Cursor[]{ 
         mTopCursor, cursor }); 
    } 
} 

底部片段

public class BottomFragment extends Fragment { 
    public Cursor mBottomCursor; 
    EmployeeDBHandler dbHandler; 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_bottom_list, container, false); 
     dbHandler = new EmployeeDBHandler(getContext()); 
     SQLiteDatabase db = dbHandler.getWritableDatabase(); 
     String table = "employees"; 
     int mStartingEmployeeID = 3500075; 
     mBottomCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + 
       "Employee_number" + "!=" + mStartingEmployeeID + " AND " + 
       "Manager_employee_number" + "=" + mStartingEmployeeID + " ORDER BY " + 
       "Last_name" + " ASC", null); 
     ListView mBottomListView = (ListView) view.findViewById(android.R.id.list); 
     BottomListViewAdapter mBottomAdapter = new BottomListViewAdapter(getContext(), mBottomCursor); 
     mBottomListView.setAdapter(mBottomAdapter); 
     return view; 
    } 
} 
+0

您還沒有在上面的snipet中的topAdapter中設置任何值(然後是NPE?) – crgarridos

+0

NPE?如果我將它分配給新的TopListCursorAdapter,我不會得到null點,但沒有任何反應。 –

+0

NPE:NullPointerException。 – crgarridos

回答

0

所以我能夠得到這個終於工作。我所做的是從bottomList中取出光標,將其與TopLists現有光標合併,然後將該光標傳遞給TopAdapter。

public void update(Cursor cursor) { 
     MergeCursor mergeCursor = new MergeCursor(new Cursor[]{cursor, mTopCursor}); 
     TopListCursorAdapter topAdapter = new TopListCursorAdapter(getContext(), mergeCursor); 
     mTopListView.setAdapter(topAdapter); 
    } 
0

除非員工可以共享的ID,這個代碼只會讓你one員工顯示在ListView中。 (在活動)

dbHandler.addEmployee(e); 
TopFragment topFragment = (TopFragment) getSupportFragmentManager().findFragmentById(R.id.topFragment); 
SQLiteDatabase db = dbHandler.getWritableDatabase(); 
final Cursor clickedEmployee = db.rawQuery("SELECT * FROM " + "employees" + " WHERE " + 
     "Employee_number" + "=" + e.getEmployee_number(), null); 
// change the adapter's Cursor 
topFragment.update(clickedEmployee); 

等都將這個代碼(在TopFragment)

int mStartingEmployeeID = 3500075; 
dbHandler = new EmployeeDBHandler(getContext()); 
SQLiteDatabase db = dbHandler.getWritableDatabase(); 
mTopCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null); 
ListView mTopListView = (ListView) view.findViewById(R.id.mTopList); 
TopListCursorAdapter topAdapter = new TopListCursorAdapter(getContext(), mTopCursor); 
mTopListView.setAdapter(topAdapter); 

您正在嘗試添加一行到適配器,不能完全取代它。所以,爲了做到這一點,我認爲您需要在您的數據庫中插入INSERT語句,然後再處理任何遊標交換,然後重新編寫您的查詢,以便您試圖插入的全部結果將返回。

例如,如果ID是自動遞增的,也許你想要WHERE Employee_number >= " + mStartingEmployeeID


此外,這可能不是解決一些問題,你違反了dbHandler實例的目的是爲「封裝」查詢。

所以,與其這樣

SQLiteDatabase db = dbHandler.getWritableDatabase(); 
mTopCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null); 

推薦的方式,簡直是

topCursor = dbHandler.getEmployeeWithId(mStartingEmployeeID); 

如果你已經有一個返回Employee類似的方法,那麼你就可以代替使Employee(Cursor c)構造你」 d這樣使用

Employee e = new Employee(dbHandler.getEmployeeWithId(mStartingEmployeeID)); 

+0

我看到從不同位置刪除查詢並將它們放入dbhandler。但是,如何幫助將bottomList點擊員工添加到頂部列表?頂部列表將始終在應用程序開始時包含該人員,他們將始終位於頂部列表中。我可以刪除查詢並在我的dbhandler中使用getEmployee方法,但這並不能幫助我從bottomList中添加單擊的事件。 –

+0

你太專注於我的答案的下半部分。頂部是更重要的一塊。您需要更新/更改查詢,以便將任何插入的員工記錄添加到數據庫**,而不是ListView,然後使用任何查詢將能夠顯示該對象。 –

+0

如果我將點擊的行添加到數據庫中,是不是將記錄添加到數據庫中兩次? –

相關問題