Android - 片段

时间:2015-07-22 21:36:31

标签: android android-actionbar fragment searchview android-actionbar-compat

我总是在片段类的下面一行获取searchView null:

SearchView searchView =(SearchView)MenuItemCompat.getActionView(searchItem);

这是我的片段类,请在底部找到onCreateOptionsMenu方法:

public class FriendsListActivity extends  Fragment implements EventListener {

    ArrayList<Users> friendList = new ArrayList<Users>();
    ArrayList<Users> blockedList = new ArrayList<Users>();
    ArrayList<Users> famliyList = new ArrayList<Users>();
    ArrayList<Users> newContactList = new ArrayList<Users>();

    ArrayList<JSONObject> finalContactList = new ArrayList<JSONObject>();
    ArrayList<JSONObject> modifiedContactList = new ArrayList<JSONObject>();

    static int count;

    private Menu optionsMenu;

    private DBHelper mydb ;

    Map<String , String> dbContectMap;

    SocketOperator socket;

    boolean isGetResult = false;

    List<String> mobileList = new ArrayList<String>();

    JSONObject changeCategoryJobj = new JSONObject();

    CutsomAdapter customFriendListAdapter;

    String headerpixurl = "images/b58a34f2-ec57-494f-821e-09ecf584449e/profileImage/stickyHeader/82508da9-bf53-488f-a09b-3bb250cc1bd2.PNG";

    String startCategory;
    String lastCategory = "start";
    int isHeader = 0;
    ListView lv1;

    private boolean isActivityInitialized = false;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        FragmentActivity    faActivity  = (FragmentActivity)    super.getActivity();
        // main layout which contains list
        LinearLayout        llLayout    = (LinearLayout)    inflater.inflate(R.layout.friends_activity_main, container, false);


        //sqlite DB
        mydb = new DBHelper(FriendsListActivity.super.getActivity());
        dbContectMap = mydb.getAllCotacts();

        socket = new SocketOperator(this);

        fetchContactsFromPhone();// from phone
        int count = 0;
        try {
            while(!isGetResult && count <= 6){
                Thread.sleep(5000);
                count++;
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //fetchContactsFromServer(mobileList);

        // friends_activity_list_row_layout , represents one item in list view
        customFriendListAdapter = new CutsomAdapter(FriendsListActivity.super.getActivity().getApplicationContext(), 
                R.layout.friends_activity_list_row_layout , finalContactList );
        // this will be list which conain items
        lv1= (ListView) llLayout.findViewById(R.id.friends_activity_custom_list);
        lv1.setStackFromBottom(false);
        lv1.setAdapter(customFriendListAdapter);

        setHasOptionsMenu(true);
        setupActionBar();
        isActivityInitialized = true;
        return llLayout;
    }

    // give a delete button to remove permanatly from list

    // same code is in LoginActivity, when ever change here also code review the LoginActivity code too
    public void fetchContactsFromPhone() {

        String phoneNumber = null;
        String email = null;

        Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
        String _ID = ContactsContract.Contacts._ID;
        String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
        String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;

        Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
        String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;

        Uri EmailCONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
        String EmailCONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
        String DATA = ContactsContract.CommonDataKinds.Email.DATA;

        //StringBuffer output = new StringBuffer();

        ContentResolver contentResolver = FriendsListActivity.super.getActivity().getContentResolver();

        Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null,
                null);

        // Loop for every contact in the phone
        if (cursor.getCount() > 0) {

            while (cursor.moveToNext()) {

                String contact_id = cursor
                        .getString(cursor.getColumnIndex(_ID));
                String name = cursor.getString(cursor
                        .getColumnIndex(DISPLAY_NAME));

                int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor
                        .getColumnIndex(HAS_PHONE_NUMBER)));

                if (hasPhoneNumber > 0) {

                    // Query and loop for every phone number of the contact
                    Cursor phoneCursor = contentResolver.query(
                            PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?",
                            new String[] { contact_id }, null);

                    while (phoneCursor.moveToNext()) {
                        phoneNumber = phoneCursor.getString(phoneCursor
                                .getColumnIndex(NUMBER));
                        // output.append("\n Phone number:" + phoneNumber);

                    }

                    phoneCursor.close();
                    Users user = new Users();
                    user.name = name;
                    user.mobileNumber = phoneNumber;
                    //friendList.add(user);
                    // check if this user/phone number is already added to server friendList
                    if( !dbContectMap.containsKey(phoneNumber)){
                        mobileList.add(phoneNumber);
                    }
                }

            }

            // outputText.setText(output);
        }

        // send to server and update mydb
        try {
            JSONObject jsonObj = new JSONObject();
            jsonObj.put("action", "addNewContactInFriendList");
            jsonObj.put("userid", MyData.getMyDataInstance().getString(MyData.USERID));
            JSONArray mobileListArray = new JSONArray(mobileList);
            jsonObj.put("mobileList", mobileListArray);

            socket.sendMessage(jsonObj);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * The Class CutsomAdapter is the adapter class for Activity ListView. The
     * currently implementation of this adapter simply display static dummy
     * contents. You need to write the code for displaying actual contents.
     */
    private class CutsomAdapter extends ArrayAdapter<JSONObject> implements
    PinnedSectionListAdapter,  Filterable {

        private LayoutInflater layoutInflater;
        private Context context;
        List<Users> userList;
        String radioGroupType;

        private OnCustomClickListener callback;

        int itemListSize = 0;

        ArrayList<JSONObject> listData;
        ArrayList<JSONObject> tempListData;

        private FriendsFilter friendsFilter;


        public CutsomAdapter(Context context, int textViewResourceId, ArrayList<JSONObject> finalArrayList) {
            super(context, textViewResourceId, finalArrayList);
            layoutInflater = LayoutInflater.from(context);
            this.context = context;
            this.listData = finalArrayList;
            this.tempListData = finalArrayList;
        }

        View convertView = null;


        class ViewHolder {
            ImageView headerImage;          
            TextView name;
            TextView mobile;            
            RadioGroup radioCategory;
            RadioButton radioButton;
        }

        class HeaderViewHolder {                
            TextView categoryName;

        }

        public void setContext(Context context) {
            this.context = context;
        }

        @Override
        public int getCount() {
            itemListSize = listData.size();
            return listData.size();
        }

        public void setListData(List<JSONObject> list) {
            this.listData = (ArrayList<JSONObject>) list;
        }

        @Override
        public JSONObject getItem(int position) {
            return listData.get(position);
        }

        @Override
        public boolean isItemViewTypePinned(int viewType) {
            boolean toBePinned = false;
            if (viewType == 1)
                toBePinned = true;
            // System.out.println("toBePinned: "+toBePinned);
            return toBePinned;
        }

        @Override
        public int getItemViewType(int position) {
            JSONObject jo = this.listData.get(position);
            int k = 0;
            isHeader = 0;
            try {

                String header = jo.getString("headerStr");
                if(header != null && "headerStr".equalsIgnoreCase("headerStr")){
                    k=1;
                    isHeader = 1;
                }

            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return k;
        }

        @Override
        public int getViewTypeCount() {
            return 2;
        }


        /*
         * (non-Javadoc)
         * 
         * @see android.widget.Adapter#getItemId(int)
         */
        @Override
        public long getItemId(int arg0) {
            return arg0;
        }


        /*
         * (non-Javadoc)
         * 
         * @see android.widget.Adapter#getView(int, android.view.View,
         * android.view.ViewGroup)
         */
        @Override
        public View getView(final int position, View convertViewx, ViewGroup parent) {

            final JSONObject jObj = (JSONObject) listData.get(position);

            View convertView = null;


            //int isHeader = 0;
            try {
                //isHeader = jObj.getInt("TYPE");
                String header = jObj.getString("headerStr"); 
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            //if (lastCategory.equalsIgnoreCase("start") || !startCategory.equalsIgnoreCase(lastCategory)) {
            if(isHeader == 1){

                final JSONObject jObjX = (JSONObject) listData.get(position);
                convertView = layoutInflater.inflate(R.layout.friends_activity_sticky_header,
                        null);
                final HeaderViewHolder headerViewHolder = new HeaderViewHolder();

                convertView.setBackgroundColor(Color.WHITE);                
                headerViewHolder.categoryName = (TextView) convertView
                        .findViewById(R.id.header);

                try {
                    String header = jObjX.getString("headerStr");                   
                    headerViewHolder.categoryName.setText(header);

                    //headerViewHolder.userProfilePic.seti();
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

            else {

                try {

                    final ViewHolder holder;
                    if (convertView == null) {
                        convertView = layoutInflater.inflate( 
                                R.layout.friends_activity_list_row_layout, null);
                    }           


                    holder = new ViewHolder();

                    holder.headerImage = (ImageView)convertView.findViewById(R.id.headerImage);
                    Picasso.with(context).load(MyData.SERVER_URL+jObj.getString("headerpixurl")).into(holder.headerImage);

                    holder.name = (TextView) convertView.findViewById(R.id.name);
                    holder.name.setText(jObj.getString("name"));

                    holder.mobile = (TextView) convertView.findViewById(R.id.mobile);
                    holder.mobile.setText(jObj.getString("mobile"));
                    if(jObj.getString("category").equalsIgnoreCase("friends")){
                        holder.radioButton = (RadioButton) convertView.findViewById(R.id.friend);
                        holder.radioButton.setChecked(true);
                    }else if(jObj.getString("category").equalsIgnoreCase("family")){
                        holder.radioButton = (RadioButton) convertView.findViewById(R.id.family);
                        holder.radioButton.setChecked(true);
                    }else if(jObj.getString("category").equalsIgnoreCase("blocked")){
                        holder.radioButton = (RadioButton) convertView.findViewById(R.id.block);
                        holder.radioButton.setChecked(true);

                    }else if(jObj.getString("category").equalsIgnoreCase("newuser")){
                        // dont do any thing let user select , which category he choose for this user
                    }   

                    holder.radioCategory = (RadioGroup) convertView.findViewById(R.id.radioCategory);

                    holder.radioCategory.setTag(position);
                    holder.radioCategory.setOnCheckedChangeListener(listener);

                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                lastCategory = startCategory;

            }

            return convertView;

        }

        // https://stackoverflow.com/questions/28574000/fill-a-listview-with-radio-button-groups-with-an-onclick-listener-in-the-adapter
        RadioGroup.OnCheckedChangeListener listener = new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int id) {

                RadioButton radio = (RadioButton)radioGroup.findViewById(radioGroup.getCheckedRadioButtonId());
                int index = (Integer) radioGroup.getTag();
                JSONObject selected = (JSONObject) getItem(index);

                try{
                    switch (id) {


                            case R.id.friend:
                                System.out.println("friend");
                                selected.put("newCategory", "friends");
                                modifiedContactList.add(selected);
                                //finalContactList.remove(index);
                                break;
                            case R.id.family:
                                System.out.println("family");
                                selected.put("newCategory", "family");
                                modifiedContactList.add(selected);
                                //finalContactList.remove(index);
                                break;
                            case R.id.block:
                                System.out.println("block");
                                selected.put("newCategory", "blocked");
                                modifiedContactList.add(selected);
                                //finalContactList.remove(index);
                                break;

                    }

                }catch(Exception ex){

                }
            }
        };

        public void resetData() {
            listData  = tempListData ;
        }


        @Override
        public Filter getFilter() {
            if (friendsFilter == null)
                friendsFilter = new FriendsFilter();

            return friendsFilter;
        }

        // https://github.com/survivingwithandroid/Surviving-with-android/blob/master/ListView_Filter_Tutorial/src/com/survivingwithandroid/listview/SimpleList/PlanetAdapter.java

        private class FriendsFilter extends Filter {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                // We implement here the filter logic
                if (constraint == null || constraint.length() == 0) {
                    // No filter implemented we return all the list
                    results.values = tempListData;
                    results.count = tempListData.size();
                }
                else {
                    // We perform filtering operation
                    List<JSONObject> nPlanetList = new ArrayList<JSONObject>();

                    for (JSONObject p : listData) {
                        try {
                            if (p.getString("name").toUpperCase().startsWith(constraint.toString().toUpperCase()))
                                nPlanetList.add(p);
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                    results.values = nPlanetList;
                    results.count = nPlanetList.size();

                }
                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                // Now we have to inform the adapter about the new list filtered
                if (results.count == 0)
                    notifyDataSetInvalidated();
                else {
                    listData = (ArrayList<JSONObject>) results.values;
                    notifyDataSetChanged();
                }

            }

        }

    }

    private void toList(List<Users> contactList, JSONArray array) throws JSONException {

        int size = array.length();
        for (int i = 0; i < size; i++) {
            JSONObject jobj = array.getJSONObject(i);
            Users user = new Users();
            user.userid = jobj.getString("userid");
            user.name = jobj.getString("name");
            //user.category = jobj.getString("category");
            user.imageURL = jobj.getString("headerpixurl");

            // #### FOR TESTING
            headerpixurl = jobj.getString("headerpixurl");

            user.mobileNumber = jobj.getString("mobile");

            contactList.add(user);
        }
        //return contactList;
    }

    //  #### FOR TESTING ####

    private void testing(JSONArray jArray, String category){


        for (count= 0; count < 5; count++) {

            try {
                JSONObject jObj = new JSONObject();

                jObj.put("userid", "1234"+count);
                jObj.put("name", "vichi"+count);
                jObj.put("mobile", "9999");
                jObj.put("headerpixurl", headerpixurl);
                jObj.put("category", category);
                jArray.put(jObj);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }

    private void mergeInList(JSONArray jArray){

        for(int i=0; i < jArray.length(); i++){
            try {
                finalContactList.add(jArray.getJSONObject(i));
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }


    @Override
    public void eventReceived(String event) throws JSONException {
        // when we will get return phone number then only we will update sqlite table
        final JSONObject eventJObjx = new JSONObject(event);

        if(isActivityInitialized){

            FriendsListActivity.super.getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        intilizeContactsList(eventJObjx);
                        customFriendListAdapter.notifyDataSetChanged();
                    }catch(Exception ex){

                    }
                }
            });

        }else{
            intilizeContactsList(eventJObjx);
        }

        //mydb.insertContact(phone, "Y");
    }


    private void intilizeContactsList(JSONObject eventJObjx) throws JSONException{
        //#### ALWAYS MAINTAIN THIS ORDER ####  
        finalContactList.clear();
        modifiedContactList.clear();
        JSONArray newuserArray = eventJObjx.getJSONArray("newuser");
        if(newuserArray.length() > 0){
            JSONObject jObj1 = new JSONObject();
            jObj1.put("headerStr", " New User");
            finalContactList.add(jObj1);
            mergeInList(newuserArray);
        }

        JSONArray friendsArray = eventJObjx.getJSONArray("friends");
        //testing(friendsArray, "friends");
        if(friendsArray.length() > 0){
            JSONObject jObj1 = new JSONObject();
            jObj1.put("headerStr", " Friends ");
            finalContactList.add(jObj1);
            mergeInList(friendsArray);
        }

        JSONArray familyArray = eventJObjx.getJSONArray("family");
        //testing(familyArray, "family");
        if(familyArray.length() > 0){
            JSONObject jObj1 = new JSONObject();
            jObj1.put("headerStr", " Family ");
            finalContactList.add(jObj1);
            mergeInList(familyArray);
        }


        JSONArray blockedArray = eventJObjx.getJSONArray("blocked");
        //testing(blockedArray, "blocked");
        if(blockedArray.length() > 0){
            JSONObject jObj1 = new JSONObject();
            jObj1.put("headerStr", " Blocked ");
            finalContactList.add(jObj1);
            mergeInList(blockedArray);
        }


        for(int i=0; i < newuserArray.length(); i++){
            //mobileToAddInFriendList.add(mobileListArray.getString(i));
            mydb.insertContact(newuserArray.getJSONObject(i).getString("mobile"), "Y");
        }

        isGetResult = true;
    }


    protected void setupActionBar() {
        final ActionBar actionBar = FriendsListActivity.super.getActivity().getActionBar();
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionBar.setDisplayUseLogoEnabled(true);
        actionBar.setLogo(R.drawable.icon);
        actionBar.setBackgroundDrawable(getResources().getDrawable(
                R.drawable.actionbar_bg));
        // actionBar.setDisplayHomeAsUpEnabled(true);
        // actionBar.setHomeButtonEnabled(true);
    }


    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        FriendsListActivity.super.getActivity().getMenuInflater().inflate(R.menu.friends_activity_menu, menu);
        this.optionsMenu = menu;
        super.onCreateOptionsMenu(menu, inflater);

        SearchManager searchManager = (SearchManager) FriendsListActivity.super.getActivity().getSystemService(Context.SEARCH_SERVICE);
        //SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);

        searchView.setSearchableInfo(searchManager.getSearchableInfo(FriendsListActivity.super.getActivity().getComponentName()));
        searchView.setIconifiedByDefault(false);

        SearchView.OnQueryTextListener textChangeListener = new SearchView.OnQueryTextListener()
        {
            @Override
            public boolean onQueryTextChange(String newText)
            {
                // this is your adapter that will be filtered
                customFriendListAdapter.getFilter().filter(newText);
                System.out.println("on text chnge text: "+newText);
                return true;
            }
            @Override
            public boolean onQueryTextSubmit(String query)
            {
                // this is your adapter that will be filtered
                customFriendListAdapter.getFilter().filter(query);
                System.out.println("on query submit: "+query);
                return true;
            }
        };
        searchView.setOnQueryTextListener(textChangeListener);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        super.onOptionsItemSelected(item);

        switch (item.getItemId()) {
        case R.id.done:
            try {
                JSONObject jsonObj = new JSONObject();
                jsonObj.put("action", "moveContact");
                jsonObj.put("userid", MyData.getMyDataInstance().getString(MyData.USERID));
                JSONArray mobileListArray = new JSONArray(modifiedContactList);
                jsonObj.put("modifiedList", mobileListArray);
                socket.sendMessage(jsonObj);
                modifiedContactList.clear();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            break;

        }
        return super.onOptionsItemSelected(item);

    }

}

这是我的menu.xml文件

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/done"
        android:icon="@drawable/ic_action_accept"
        app:showAsAction="always"
        android:title="@string/upload"/>
    <item
        android:id="@+id/action_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        android:icon="@drawable/ic_launcher"
        app:showAsAction="always|collapseActionView"
        android:maxWidth="100dp"
        android:title="Search"/>
</menu>

这是日志片段:

07-23 15:18:59.015    1841-1841/com.woohoo E/AndroidRuntime? FATAL EXCEPTION: main
Process: com.woohoo, PID: 1841
java.lang.NullPointerException
        at com.woohoo.FriendsListActivity.onCreateOptionsMenu(FriendsListActivity.java:797)
        at android.support.v4.app.Fragment.performCreateOptionsMenu(Fragment.java:1871)
        at android.support.v4.app.FragmentManagerImpl.dispatchCreateOptionsMenu(FragmentManager.java:2001)
        at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:278)
        at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:436)
        at com.android.internal.policy.impl.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java:800)
        at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:221)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
        at android.view.Choreographer.doCallbacks(Choreographer.java:574)
        at android.view.Choreographer.doFrame(Choreographer.java:543)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)

令人惊讶的是它在Eclipse中运行良好,但在Android Studio中提供了nullpointerexception。

我已尝试使用与以下链接相同的配置: Android - NullPointerException on SearchView in Action Bar

Android search with Fragments

1 个答案:

答案 0 :(得分:0)

问题在于你的片段。根据这条线:

new MyThreadClass.start();

NullPointerException在您的FriendsListActivity中,特别是在onCreateOptionsMenu,第797行

我浏览了你的onCreateOptionsMenu,可能还有一些事情是调用NullPointerException。您可以更轻松地找到第797行(如果您不知道如何在IDE中更改行号,请选中​​thisthis

调用片段FriendsListActivity也不是一个好主意。例如,将其重命名为FriendsListFragment以避免混淆。