Search code examples
javaclassconstructorencapsulation

Move nested class to external file


In my main activity file, I have two classes that I want to move out to new files (just for the sake of cleaning the code a bit). The two classes are AdapterForPostsListView and PostFilter. I tried using the Eclipse's "Refractor" -> "Move type to new file" but it generated errors since some vars are defined in the main/parent activity.

public class Amawal extends SherlockActivity {

    // Declare Variables
    ListView list;
    EditText editsearch;
    private List<Post> wp_posts = null;
    private AdapterForPostsListView dataAdapter = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home_activity);

        // Initialise DB; copy it from assets to system if not already done.
        AmawalDB db = new AmawalDB(this, null, 1);
        db.initialise();

        wp_posts = db.getAllPosts();

        populateListView();
        registerClickCallback();
    }

    private void populateListView() {
        // create an ArrayAdaptar from the Posts object
        dataAdapter = new AdapterForPostsListView(this, R.layout.item_view, wp_posts);
        ListView list = (ListView) findViewById(R.id.posts_container_listview);

        // Assign adapter to ListView
        list.setAdapter(dataAdapter);

        // enables filtering for the contents of the given ListView
        list.setTextFilterEnabled(true);

    }

    /*
     * http://www.mysamplecode.com/2012/07/android-listview-custom-layout-filter.
     * html
     */
    private class AdapterForPostsListView extends ArrayAdapter<Post> {

        private ArrayList<Post> originalList;
        private ArrayList<Post> newList;
        private PostFilter filter;

        public AdapterForPostsListView(Context context, int textViewResourceId, List<Post> countryList) {
            super(context, textViewResourceId, countryList);
            this.newList = new ArrayList<Post>();
            this.newList.addAll(countryList);
            this.originalList = new ArrayList<Post>();
            this.originalList.addAll(countryList);
        }

        @Override
        public Filter getFilter() {
            if (filter == null) {
                filter = new PostFilter();
            }
            return filter;
        }

        private class ViewHolder {
            TextView holder_post_title;
            TextView holder_post_content;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolder holder = null;
            Log.v("ConvertView", String.valueOf(position));
            if (convertView == null) {

                LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = vi.inflate(R.layout.item_view, null);

                holder = new ViewHolder();
                holder.holder_post_title = (TextView) convertView.findViewById(R.id.item_postTitle);
                holder.holder_post_content = (TextView) convertView.findViewById(R.id.item_postContent);

                convertView.setTag(holder);

            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            Post post = newList.get(position);
            holder.holder_post_title.setText(post.getpostTitle());
            holder.holder_post_content.setText(post.getPostContent());

            return convertView;

        }

        private class PostFilter extends Filter {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

                constraint = constraint.toString().toLowerCase(Locale.getDefault());
                FilterResults result = new FilterResults();
                if (constraint != null && constraint.toString().length() > 0) {
                    ArrayList<Post> filteredItems = new ArrayList<Post>();

                    for (int i = 0, l = originalList.size(); i < l; i++) {
                        Post post = originalList.get(i);
                        if (post.toString().toLowerCase(Locale.getDefault()).contains(constraint))
                            filteredItems.add(post);
                    }
                    result.count = filteredItems.size();
                    result.values = filteredItems;
                } else {
                    synchronized (this) {
                        result.values = originalList;
                        result.count = originalList.size();
                    }
                }
                return result;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {

                newList = (ArrayList<Post>) results.values;
                notifyDataSetChanged();
                clear();
                for (int i = 0, l = newList.size(); i < l; i++)
                    add(newList.get(i));
                notifyDataSetInvalidated();
            }
        }
    }

    private void registerClickCallback() {
        ListView list = (ListView) findViewById(R.id.posts_container_listview);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View viewClicked, int position, long id) {

                Post clickedPost = wp_posts.get(position);

                // New intent
                Intent i = new Intent(Amawal.this, SinglePost.class);

                int ID = clickedPost.getID();

                String message = "You clicked position " + position + " Which is ID " + ID;
                Toast.makeText(Amawal.this, message, Toast.LENGTH_LONG).show();

                // supply a Tag
                i.putExtra("ID", ID);

                // launch activity
                startActivity(i);
            }
        });
    }

    // Create the options menu
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Get the options menu view from menu.xml in menu folder
        getSupportMenuInflater().inflate(R.menu.menu, menu);

        // Locate the EditText in menu.xml
        editsearch = (EditText) menu.findItem(R.id.menu_search).getActionView();

        // Listen to search text change
        editsearch.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable s) {
                String text = editsearch.getText().toString().toLowerCase(Locale.getDefault());

                dataAdapter.getFilter().filter(text);
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

            }

            @Override
            public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

            }

        });

        // Show the search menu item in menu.xml
        MenuItem menuSearch = menu.findItem(R.id.menu_search);

        menuSearch.setOnActionExpandListener(new OnActionExpandListener() {

            // Menu Action Collapse
            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                // Empty EditText to remove text filtering
                editsearch.setText("");
                editsearch.clearFocus();
                return true;
            }

            // Menu Action Expand
            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                // Focus on EditText
                editsearch.requestFocus();

                // Force the keyboard to show on EditText focus
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
                return true;
            }
        });

        // Show the about us menu item in menu.xml
        MenuItem menuAbout = menu.findItem(R.id.menu_about);

        // Capture the about menu click
        menuAbout.setOnMenuItemClickListener(new OnMenuItemClickListener() {

            @Override
            public boolean onMenuItemClick(MenuItem item) {
                // TODO Auto-generated method stub
                // Open the about us activity
                Toast.makeText(getApplicationContext(), "Nothing here!", Toast.LENGTH_LONG).show();
                return false;
            }

        });

        return true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Close the database here
    }

}

Since I'm new to Java's OOP I have problems getting the new created classes to work :(


Solution

  • Add a constructor to the classes that you are moving out that takes as arguments the variables you need from the parent class. Store those values as member variables of that class which its methods can access.

    For instance, if we assume for simplicity's sake that only originalList needed to be passed through:

    class PostFilter extends Filter {
        private ArrayList<Post> originalList;
    
        public PostFilter(ArrayList<Post> originalList) {
            this.originalList = originalList;
        }
    ...