Question

I have a NavigationDrawer that call other pages depending on the selected value on the menu. it is being loaded via fragment.

MainActivity.Java

package medapp.app;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity
{
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mDrawerToggle;

    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    private String[] mActions;



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

        mTitle = mDrawerTitle = getTitle();
        mActions = getResources().getStringArray(R.array.action_array);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        // set a custom shadow that overlays the main content when the drawer opens
        //mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
        // set up the drawer's list view with items and click listener
        mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.drawer_list_item, mActions));
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        // enable ActionBar app icon to behave as action to toggle nav drawer
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        // ActionBarDrawerToggle ties together the the proper interactions
        // between the sliding drawer and the action bar app icon
        mDrawerToggle = new ActionBarDrawerToggle(
                this,                  /* host Activity */
                mDrawerLayout,         /* DrawerLayout object */
                R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description for accessibility */
                R.string.drawer_close  /* "close drawer" description for accessibility */
        ) {
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if (savedInstanceState == null) {
            selectItem(0);
        }
    }

    public void onItemClick(AdapterView<?> adapter, View view,
                            int position, long id) {
        Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
                Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    /* Called whenever we call invalidateOptionsMenu() */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // If the nav drawer is open, hide action items related to the content view
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        return super.onPrepareOptionsMenu(menu);
    }


    /* */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // The action bar home/up action should open or close the drawer.
        // ActionBarDrawerToggle will take care of this.
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
                return super.onOptionsItemSelected(item);
        //}
    }


    /* The click listener for ListView in the navigation drawer */
    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }
    }

    private void selectItem(int position) {
        // update the main content by replacing fragments
        Fragment fragment = new ActionFragment();
        Bundle args = new Bundle();
        args.putInt(ActionFragment.ARG_ACTION1_NUMBER, position);
        fragment.setArguments(args);

        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        setTitle(mActions[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    /**
     * When using the ActionBarDrawerToggle, you must call it during
     * onPostCreate() and onConfigurationChanged()...
     */

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggls
        mDrawerToggle.onConfigurationChanged(newConfig);
    }


}

HERE is my Fragment.Java that calls the xml layout for each choices.

package medapp.app;

import android.app.*;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import org.json.JSONArray;
import org.json.JSONException;

public class ActionFragment extends Fragment
{
    public static final String ARG_ACTION1_NUMBER = "Fragment_layout";
    public JSONArray blogData;

    public ActionFragment() {
        // Empty constructor required for fragment subclasses
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
        int i = getArguments().getInt(ARG_ACTION1_NUMBER);

        if (i == 0)
        {
            rootView = inflater.inflate(R.layout.fragment_layout, container, false);
        }
        else if(i == 1)
        {
            PostActivity getBlogPostTask = new PostActivity();
            getBlogPostTask.execute();
            rootView = inflater.inflate(R.layout.fragment_articles, container, false);
        }
        else if(i == 2)
        {
            rootView = inflater.inflate(R.layout.fragment_news, container, false);
            PostActivity getBlogPostTask = new PostActivity();
            getBlogPostTask.execute();
        }
        else if(i == 3)
        {
            rootView = inflater.inflate(R.layout.fragment_signin, container, false);
        }
        return rootView;
    }

    public void updatelist() {

        if (blogData == null)
        {
            // TODO: update list when null.
        }
        else
        {
            try
            {
               Log.d("TAG", blogData.toString(2));
            } catch (JSONException e) {
                Log.e("TAG", "Exception Caught: ", e);
            }
        }
    }

}

Now I created layout_listitem.xml which I want to load inside fragment_article.xml as an item in the listview.

Any idea how do I make the layout_listitem show as a layout design inside the listview in the fragment_article.xml.

All the tutorials I found in the internet requires the fragment_article.xml to be called in the main activity.

Was it helpful?

Solution

If you know that fragment_article.xml gives you ListView.java then the following code should solve your problem.

else if(i == 1) 
{
    PostActivity getBlogPostTask = new PostActivity();
    getBlogPostTask.execute();
    rootView = inflater.inflate(R.layout.fragment_articles, container, false);
    ListView listView = (ListView) rootView;
    //convert JSONArray to ArrayList<JSONObject>
    List<JSONOject> data = //convert blogData
    ArrayAdapter<JSONObject> adapter = new ArrayAdapter<JSONObject(getActivity(), R.layout.layout_listitem.xml, data);
    listView.setAdapter(adapter); 
}

There is no point to write more code here. It depends on how you plan to load your data.

There are things you need to know for further enhancements:

  • ArrayAdapter in above code will take JSONObject.toString value and call setText on layout_listitem.xml assuming it's TextView. I guess it's not so you can extends ArrayAdapter and override method getView().
  • You can keep ArrayAdapter as a member of your ActionFragment and initialise it differently for every ARG_ACTION1_NUMBER type. This is useful if you plan to use same data but show in different layouts. Also if you plan to load data outside of your ActionFragment then in updateList() method you will have easy access to that adapter.
  • If you know the JSON you are loading consider creating java POJOs and use GSON or Jackson libraries. Then in your adapter you could have your own classes. It's much easier to work with POJOs than parsing JSONs yourself.

OTHER TIPS

You can get the ListView in fragment_articles like this:

PostActivity getBlogPostTask = new PostActivity();
getBlogPostTask.execute();
rootView = inflater.inflate(R.layout.fragment_articles, container, false);

ListView listView = (ListView) rootView.findViewById(R.id.list);  // assuming that the id of your listview in xml file is "list"

Now, you need to create an adapter class extending BaseAdapter or ArrayAdapter. And inside that adapter's getView method you need to inflate your layout_listitem.

public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (view == null) {
        LayoutInflater inflater = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.layout_listitem, null);
    }

    .....................

    return view;
}

After that, set your custom adapter as the data source of your listview.

Adapter adapter = new MyCustomAdapter(...);
listView.setAdapter(adapter);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top