LongClick to Delete List Item (Using Fragments in Master-Detail) - android

I've created a Master-Detail Flow application, and I'm using all of the default files that Eclipse/Android creates. I created a project using the template, and haven't modified anything in it, except to add the methods discussed below for deleting the item.
I need to implement an onItemLongClickListener so that when I longpress an item in the list, that item is deleted. I don't want an alert or a confirmation or to select multiple items, I just want the one I longclick to go away.
I've found several tutorials on the subject, but my issue is that they aren't using fragments, so I'm getting a bit confused about what methods go where. (This is the one I'm mostly working with: AndroidForBeginners)
If I'm understanding correctly, I should only be using the ItemListActivity and ItemListFragment. I understand that methods in the Fragment will be called in the Activity (such as the default onItemSelected that comes with the template). I understand that the removeItemFromList method (from the linked tutorial) removes the item from the array and notifies the adapter to update the list. My problem is, I don't know where the array and adapter are within the Master-Detail fragments and activities. There's an ArrayList in the DummyContent, so I thought maybe if I call removeItem in the fragment, then send it to the Activity, then call it from the DummyContent class it would work. But it doesn't, and I'm stuck.
Any advice would be much appreciated!
As requested, here is the code I'm currently using. As I said, just the default android template.
ItemListActivity.java
package Andrea.deletelistitem;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
/**
* An activity representing a list of Items. This activity
* has different presentations for handset and tablet-size devices. On
* handsets, the activity presents a list of items, which when touched,
* lead to a {#link ItemDetailActivity} representing
* item details. On tablets, the activity presents the list of items and
* item details side-by-side using two vertical panes.
* <p>
* The activity makes heavy use of fragments. The list of items is a
* {#link ItemListFragment} and the item details
* (if present) is a {#link ItemDetailFragment}.
* <p>
* This activity also implements the required
* {#link ItemListFragment.Callbacks} interface
* to listen for item selections.
*/
public class ItemListActivity extends FragmentActivity
implements ItemListFragment.Callbacks {
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_list);
if (findViewById(R.id.item_detail_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
((ItemListFragment) getSupportFragmentManager()
.findFragmentById(R.id.item_list))
.setActivateOnItemClick(true);
}
// TODO: If exposing deep links into your app, handle intents here.
}
/**
* Callback method from {#link ItemListFragment.Callbacks}
* indicating that the item with the given ID was selected.
*/
#Override
public void onItemSelected(String id) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id);
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, ItemDetailActivity.class);
detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
}
}
}
ItemListFragment.java
package Andrea.deletelistitem;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import Andrea.deletelistitem.dummy.DummyContent;
/**
* A list fragment representing a list of Items. This fragment
* also supports tablet devices by allowing list items to be given an
* 'activated' state upon selection. This helps indicate which item is
* currently being viewed in a {#link ItemDetailFragment}.
* <p>
* Activities containing this fragment MUST implement the {#link Callbacks}
* interface.
*/
public class ItemListFragment extends ListFragment {
/**
* The serialization (saved instance state) Bundle key representing the
* activated item position. Only used on tablets.
*/
private static final String STATE_ACTIVATED_POSITION = "activated_position";
/**
* The fragment's current callback object, which is notified of list item
* clicks.
*/
private Callbacks mCallbacks = sDummyCallbacks;
/**
* The current activated item position. Only used on tablets.
*/
private int mActivatedPosition = ListView.INVALID_POSITION;
/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
* selections.
*/
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(String id);
}
/**
* A dummy implementation of the {#link Callbacks} interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
#Override
public void onItemSelected(String id) {
}
};
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public ItemListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO: replace with a real list adapter.
setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(
getActivity(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1,
DummyContent.ITEMS));
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Restore the previously serialized activated item position.
if (savedInstanceState != null
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
#Override
public void onDetach() {
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
}
#Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
/**
* Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched.
*/
public void setActivateOnItemClick(boolean activateOnItemClick) {
// When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched.
getListView().setChoiceMode(activateOnItemClick
? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
private void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
getListView().setItemChecked(mActivatedPosition, false);
} else {
getListView().setItemChecked(position, true);
}
mActivatedPosition = position;
}
}
DummyContent.java
package Andrea.deletelistitem.dummy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Helper class for providing sample content for user interfaces created by
* Android template wizards.
* <p>
* TODO: Replace all uses of this class before publishing your app.
*/
public class DummyContent {
/**
* An array of sample (dummy) items.
*/
public static List<DummyItem> ITEMS = new ArrayList<DummyItem>();
/**
* A map of sample (dummy) items, by ID.
*/
public static Map<String, DummyItem> ITEM_MAP = new HashMap<String, DummyItem>();
static {
// Add 3 sample items.
addItem(new DummyItem("1", "Item 1"));
addItem(new DummyItem("2", "Item 2"));
addItem(new DummyItem("3", "Item 3"));
}
private static void addItem(DummyItem item) {
ITEMS.add(item);
ITEM_MAP.put(item.id, item);
}
/**
* A dummy item representing a piece of content.
*/
public static class DummyItem {
public String id;
public String content;
public DummyItem(String id, String content) {
this.id = id;
this.content = content;
}
#Override
public String toString() {
return content;
}
}
}
This is the method from the tutorial:
protected void removeItemFromList(int position) {
final int deletePosition = position;
AlertDialog.Builder alert = new AlertDialog.Builder(
MainActivity.this);
alert.setTitle("Delete");
alert.setMessage("Do you want delete this item?");
alert.setPositiveButton("YES", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TOD O Auto-generated method stub
// main code on after clicking yes
arr.remove(deletePosition);
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
}
});
alert.setNegativeButton("CANCEL", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
alert.show();
}
This is the method with my modifications, to remove the confirmation alert:
protected void removeItemFromList(int position) {
arr.remove(position);
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
}
In this method, I think ITEMS from the DummyContent would replace the arr array, because it's an ArrayList. I'm not sure about the adapter, though.

There's a method on any Fragment called onActivityCreated You want to #Override that method.
Then, inside it, using getListView() you can attach an onLongItemClickListener().
Like so:
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//Here you implement your code. Basically delete an item from
// the underlying data structure of your adapter, and then...
setListAdapter(.....); //re-set the list adapter.
return false;
}
});

Related

Multiple actionbar master/detail (one for master and one for detail)

I'm trying to create an application using the Master/Detail Flow template provided by Android.
I'm trying to add multiple actionbar menu items to both the master and detail portions of the actionbar.
I have use the example of Android studio but when i set the different menu for master e for detail, is show only the menu (to right) .
the Activity detail is:
public class PDetailActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_p_detail);
// Show the Up button in the action bar.
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// savedInstanceState is non-null when there is fragment state
// saved from previous configurations of this activity
// (e.g. when rotating the screen from portrait to landscape).
// In this case, the fragment will automatically be re-added
// to its container so we don't need to manually add it.
// For more information, see the Fragments API guide at:
//
// http://developer.android.com/guide/components/fragments.html
//
if (savedInstanceState == null) {
// Create the detail fragment and add it to the activity
// using a fragment transaction.
Bundle arguments = new Bundle();
arguments.putString(PDetailFragment.ARG_ITEM_ID, getIntent().getStringExtra(PatientDetailFragment.ARG_ITEM_ID));
PatientDetailFragment fragment = new PDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction().add(R.id.p_detail_container, fragment).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_p_detail, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
navigateUpTo(new Intent(this, PListActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
the fragment detail is:
public class PDetailFragment extends Fragment {
/**
* The fragment argument representing the item ID that this fragment
* represents.
*/
public static final String ARG_ITEM_ID = "item_id";
/**
* The dummy content this fragment is presenting.
*/
private PObj mItem;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public PDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
((PatientDetailActivity)getActivity()).getSupportActionBar().setTitle("Detail");
if (getArguments().containsKey(ARG_ITEM_ID)) {
// Load the dummy content specified by the fragment
// arguments. In a real-world scenario, use a Loader
// to load content from a content provider.
mItem = PListFragment.pObjHashMap.get(getArguments().getString(ARG_ITEM_ID));
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_p_detail, container, false);
// Show the dummy content as text in a TextView.
if (mItem != null) {
((TextView) rootView.findViewById(R.id.p_detail)).setText(mItem.name);
}
return rootView;
}
}
The activity master:
public class PListActivity extends BaseActivity implements PListFragment.Callbacks {
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_p_list);
// Show the Up button in the action bar.
// getActionBar().setDisplayHomeAsUpEnabled(true);
if (findViewById(R.id.p_detail_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
((PListFragment) getSupportFragmentManager()
.findFragmentById(R.id.p_list))
.setActivateOnItemClick(true);
}
// TODO: If exposing deep links into your app, handle intents here.
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_p, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
// navigateUpFromSameTask(this);
SharedPreferenceObj sp = MySharedPref.getSharedPref(getApplicationContext());
sp.setLast_id_office(StaticValues.ID);
MySharedPref.setSharedPref(getApplicationContext(), sp);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Callback method from {#link PListFragment.Callbacks}
* indicating that the item with the given ID was selected.
*/
#Override
public void onItemSelected(String id) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
Bundle arguments = new Bundle();
arguments.putString(PatientDetailFragment.ARG_ITEM_ID, id);
PatientDetailFragment fragment = new PDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.p_detail_container, fragment)
.commit();
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent dIntent = new Intent(this, PDetailActivity.class);
dIntent.putExtra(PDetailFragment.ARG_ITEM_ID, id);
startActivity(dIntent);
}
}
#Override
public void onBackPressed() {
SharedPreferenceObj sp = MySharedPref.getSharedPref(getApplicationContext());
sp.setLast_id_office(StaticValues.ID);
MySharedPref.setSharedPref(getApplicationContext(),sp);
super.onBackPressed();
}
}
the fragment master is:
public class PListFragment extends ListFragment {
//DummyContent dummyContent ;
public static List<PObj> pObjArrayList = new ArrayList<PObj>();
public static Map<String, PObj> pObjHashMap = new HashMap<String, PObj>();
/**
* The serialization (saved instance state) Bundle key representing the
* activated item position. Only used on tablets.
*/
private static final String STATE_ACTIVATED_POSITION = "activated_position";
/**
* The fragment's current callback object, which is notified of list item
* clicks.
*/
private Callbacks mCallbacks = sDummyCallbacks;
/**
* The current activated item position. Only used on tablets.
*/
private int mActivatedPosition = ListView.INVALID_POSITION;
/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
* selections.
*/
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(String id);
}
/**
* A dummy implementation of the {#link Callbacks} interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
#Override
public void onItemSelected(String id) {
}
};
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public PListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
((PListActivity)getActivity()).getSupportActionBar().setTitle("Master");
pObjArrayList.clear();
pObjHashMap.clear();
for (int i=0;i<10;i++) {
patientObjArrayList.add(new PObj(i+"","name"+i,"address"+i));
patientObjHashMap.put(i+"",new PObj(i+"","name"+i,"address"+i));
}
setListAdapter(new ArrayAdapter<PObj>(getActivity(), android.R.layout.simple_list_item_activated_1,
android.R.id.text1, patientObjArrayList));
// TODO: replace with a real list adapter.
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Restore the previously serialized activated item position.
if (savedInstanceState != null
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Activity activity = (Activity) context;
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
#Override
public void onDetach() {
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
}
#Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(pObjArrayList.get(position).id);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
/**
* Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched.
*/
public void setActivateOnItemClick(boolean activateOnItemClick) {
// When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched.
getListView().setChoiceMode(activateOnItemClick
? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
private void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
getListView().setItemChecked(mActivatedPosition, false);
} else {
getListView().setItemChecked(position, true);
}
mActivatedPosition = position;
}
}
The problem is that i show only one menu (master) and no the menu (detail)
in this screenshot
in this screenshot I have only one menu and the + is on the right instead of the left next to the title "Master".
In the part relating to the detail is missing from the title and even the symbol X.
how can fix my problem?

WebView with FragmentStatePagerAdapter goes blank on calling setCurrentItem

I am working on Swipe Views with Tabs. The code provided in the "EffectiveNavigation" project at the Creating Swipe Views with Tabs page provides a solid starting ground. Experimenting further I added an OnClickListener to the given TextView and added a setCurrentItem to the onClick method. This behaves as expected and the ViewPager jumps to the requested page.
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class DemoObjectFragment extends Fragment {
public static final String ARG_OBJECT = "object";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_collection_object, container, false);
Bundle args = getArguments();
((TextView) rootView.findViewById(android.R.id.text1)).setText(
Integer.toString(args.getInt(ARG_OBJECT)));
((TextView) rootView.findViewById(android.R.id.text1)).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
/*
*setCurrentPagerItem(5); -> omitted here to reduce complexity
*/
mViewPager.setCurrentItem(5);
}
});
return rootView;
}
}
As the project I'm working on requires the loading of static webpages instead of text. I replaced the TextView with a WebView to load a different webpage at every swipe. This works perfectly well. Click events from the HTML side are handled by a JavascriptInterface I have implemented.
It is here that I'm facing a problem. The setCurrentPagerItem method works perfectly well when called outside of the JavascriptInterface. When called from within the JavascriptInterface the WebView shows a blank screen and stays so until a swipe to the right or left is made. A swipe to the right displays the next page to the one requested and a swipe to the left displays the requested page. LogCat shows no errors and this behaviour is consistent across a 4.3 based emulator and a Nexus 7 running 4.4.4. I shall provide the entire code below.
public class CollectionDemoActivity extends FragmentActivity {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide fragments representing
* each object in a collection. We use a {#link android.support.v4.app.FragmentStatePagerAdapter}
* derivative, which will destroy and re-create fragments as needed, saving and restoring their
* state in the process. This is important to conserve memory and is a best practice when
* allowing navigation between objects in a potentially large collection.
*/
DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
/**
* The {#link android.support.v4.view.ViewPager} that will display the object collection.
*/
ViewPager mViewPager;
private static Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_collection_demo);
context = this;
// Create an adapter that when requested, will return a fragment representing an object in
// the collection.
//
// ViewPager and its adapters use support library fragments, so we must use
// getSupportFragmentManager.
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getSupportFragmentManager());
// Set up action bar.
final ActionBar actionBar = getActionBar();
// Specify that the Home button should show an "Up" caret, indicating that touching the
// button will take the user one step up in the application's hierarchy.
actionBar.setDisplayHomeAsUpEnabled(true);
final OnPageChangeListener mPageChangeListener = new OnPageChangeListener() {
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
#Override
public void onPageSelected(int pos) {
final Toast pageNo;
pageNo = Toast.makeText(context,"PAGE "+(Integer.toString(pos+1))+"/100",Toast.LENGTH_SHORT);
pageNo.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
pageNo.cancel();
}
}, 100);
}
};
// Set up the ViewPager, attaching the adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mDemoCollectionPagerAdapter);
mViewPager.setOnPageChangeListener(mPageChangeListener);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This is called when the Home (Up) button is pressed in the action bar.
// Create a simple intent that starts the hierarchical parent activity and
// use NavUtils in the Support Package to ensure proper handling of Up.
Intent upIntent = new Intent(this, MainActivity.class);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// This activity is not part of the application's task, so create a new task
// with a synthesized back stack.
TaskStackBuilder.from(this)
// If there are ancestor activities, they should be added here.
.addNextIntent(upIntent)
.startActivities();
finish();
} else {
// This activity is part of the application's task, so simply
// navigate up to the hierarchical parent activity.
NavUtils.navigateUpTo(this, upIntent);
}
return true;
}
return super.onOptionsItemSelected(item);
}
private void setCurrentPagerItem(int item) {
mViewPager.setCurrentItem(item);
}
/**
* A {#link android.support.v4.app.FragmentStatePagerAdapter} that returns a fragment
* representing an object in the collection.
*/
public static class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
public DemoCollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = new DemoObjectFragment();
Bundle args = new Bundle();
args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1); // Our object is just an integer :-P
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
// For this contrived example, we have a 100-object collection.
return 100;
}
#Override
public CharSequence getPageTitle(int position) {
return "OBJECT " + (position + 1);
}
}
/**
* A dummy fragment representing a section of the app, but that simply displays dummy text.
*/
public static class DemoObjectFragment extends Fragment {
public static final String ARG_OBJECT = "object";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_collection_object, container, false);
Bundle args = getArguments();
final WebView webView = (WebView) rootView.findViewById(R.id.webView);
switch(args.getInt(ARG_OBJECT)) {
case 1 :
webView.loadUrl("file:///android_asset/html/index.html");
break;
default :
webView.loadUrl("file:///android_asset/html/page_"+(Integer.toString(args.getInt(ARG_OBJECT)-1))+".html");
break;
}
WebSettings ws = webView.getSettings();
ws.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new Object()
{
#JavascriptInterface
public void toPage(String pageNo) {
((CollectionDemoActivity) getActivity()).setCurrentPagerItem(4);
}
}, "external");
return rootView;
}
}
}
I could be wrong but it sounds like you are not updating on the UIThread.
You could try something like this.
getActivity().runOnUiThread(new Runnable(){
#Override
public void run() {
((CollectionDemoActivity) getActivity()).setCurrentPagerItem(4);
}
});

How to disable the pinned header feture on the Sticky grid view in android

What i am trying to do ::
I want header for a certain set of rows one after another
What i am using:: Sticky Header( i am running this sample)
What is happening::
Project runs well but when i scroll the header goes and sits on top until the next header comes
Question:: (Disabling pinned header & enable the header scroll along with grid)
I want to disable this feature so that the header scrolls along with
gridview being scrolled instead of waiting for the next header
I have seen this feature possible in expandable listview but how to
implement this here
ItemDetailFragment.java
public class ItemDetailFragment extends Fragment {
/**
* The fragment argument representing the item ID that this fragment
* represents.
*/
public static final String ARG_ITEM_ID = "item_id";
/**
* The dummy content this fragment is presenting.
*/
private int mItem;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public ItemDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
// Load the dummy content specified by the fragment
// arguments. In a real-world scenario, use a Loader
// to load content from a content provider.
mItem = getArguments().getInt(ARG_ITEM_ID);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false);
((TextView) rootView.findViewById(R.id.item_detail)).setText(getResources().getStringArray(R.array.countries)[mItem]);
return rootView;
}
}
ItemListActivity.java
public class ItemListActivity extends ActionBarActivity implements ItemListFragment.Callbacks {
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
/**
* Callback method from {#link ItemListFragment.Callbacks} indicating that
* the item with the given ID was selected.
*/
#Override
public void onItemSelected(int id) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
Bundle arguments = new Bundle();
arguments.putInt(ItemDetailFragment.ARG_ITEM_ID, id);
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, ItemDetailActivity.class);
detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_list);
if (findViewById(R.id.item_detail_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
((ItemListFragment) getSupportFragmentManager().findFragmentById(R.id.item_list)).setActivateOnItemClick(true);
}
// TODO: If exposing deep links into your app, handle intents here.
}
}
ItemListFragment.java
public class ItemListFragment extends Fragment implements OnItemClickListener,
OnHeaderClickListener, OnHeaderLongClickListener {
private static final String KEY_LIST_POSITION = "key_list_position";
/**
* A dummy implementation of the {#link Callbacks} interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
#Override
public void onItemSelected(int id) {
}
};
/**
* The serialization (saved instance state) Bundle key representing the
* activated item position. Only used on tablets.
*/
private static final String STATE_ACTIVATED_POSITION = "activated_position";
/**
* The current activated item position. Only used on tablets.
*/
private int mActivatedPosition = ListView.INVALID_POSITION;
/**
* The fragment's current callback object, which is notified of list item
* clicks.
*/
private Callbacks mCallbacks = sDummyCallbacks;
private int mFirstVisible;
private GridView mGridView;
private Menu mMenu;
private Toast mToast;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public ItemListFragment() {
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks)activity;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_item_list, menu);
mMenu = menu;
menu.findItem(R.id.menu_toggle_sticky).setChecked(
((StickyGridHeadersGridView)mGridView).areHeadersSticky());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_item_grid, container, false);
}
#Override
public void onDetach() {
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
}
#Override
public void onHeaderClick(AdapterView<?> parent, View view, long id) {
String text = "Header " + ((TextView)view.findViewById(android.R.id.text1)).getText() + " was tapped.";
if (mToast == null) {
mToast = Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT);
} else {
mToast.setText(text);
}
mToast.show();
}
#Override
public boolean onHeaderLongClick(AdapterView<?> parent, View view, long id) {
String text = "Header " + ((TextView)view.findViewById(android.R.id.text1)).getText() + " was long pressed.";
if (mToast == null) {
mToast = Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT);
} else {
mToast.setText(text);
}
mToast.show();
return true;
}
#Override
public void onItemClick(AdapterView<?> gridView, View view, int position, long id) {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(position);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_toggle_sticky:
item.setChecked(!item.isChecked());
((StickyGridHeadersGridView)mGridView)
.setAreHeadersSticky(!((StickyGridHeadersGridView)mGridView)
.areHeadersSticky());
return true;
case R.id.menu_use_list_adapter:
mGridView.setAdapter(new ArrayAdapter<String>(getActivity(), R.layout.item,
getResources().getStringArray(R.array.countries)));
mMenu.findItem(R.id.menu_use_list_adapter).setVisible(false);
mMenu.findItem(R.id.menu_use_sticky_adapter).setVisible(true);
mMenu.findItem(R.id.menu_toggle_sticky).setVisible(false);
return true;
case R.id.menu_use_sticky_adapter:
mGridView.setAdapter(new StickyGridHeadersSimpleArrayAdapter<String>(getActivity()
.getApplicationContext(), getResources().getStringArray(R.array.countries),
R.layout.header, R.layout.item));
mMenu.findItem(R.id.menu_use_list_adapter).setVisible(true);
mMenu.findItem(R.id.menu_toggle_sticky).setVisible(true);
mMenu.findItem(R.id.menu_use_sticky_adapter).setVisible(false);
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mGridView = (GridView)view.findViewById(R.id.asset_grid);
mGridView.setOnItemClickListener(this);
/*
* Currently set in the XML layout, but this is how you would do it in
* your code.
*/
// mGridView.setColumnWidth((int) calculatePixelsFromDips(100));
// mGridView.setNumColumns(StickyGridHeadersGridView.AUTO_FIT);
mGridView.setAdapter(new StickyGridHeadersSimpleArrayAdapter<String>(getActivity()
.getApplicationContext(), getResources().getStringArray(R.array.countries),
R.layout.header, R.layout.item));
if (savedInstanceState != null) {
mFirstVisible = savedInstanceState.getInt(KEY_LIST_POSITION);
}
mGridView.setSelection(mFirstVisible);
// Restore the previously serialized activated item position.
if (savedInstanceState != null && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
}
((StickyGridHeadersGridView)mGridView).setOnHeaderClickListener(this);
((StickyGridHeadersGridView)mGridView).setOnHeaderLongClickListener(this);
setHasOptionsMenu(true);
}
/**
* Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void setActivateOnItemClick(boolean activateOnItemClick) {
// When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
mGridView.setChoiceMode(activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
}
#SuppressLint("NewApi")
private void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
mGridView.setItemChecked(mActivatedPosition, false);
} else {
mGridView.setItemChecked(position, true);
}
mActivatedPosition = position;
}
/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
* selections.
*/
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(int position);
}
}
ItemDetailActivity.java
public class ItemDetailActivity extends ActionBarActivity {
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpTo(this, new Intent(this, ItemListActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_detail);
// Show the Up button in the action bar.
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// savedInstanceState is non-null when there is fragment state
// saved from previous configurations of this activity
// (e.g. when rotating the screen from portrait to landscape).
// In this case, the fragment will automatically be re-added
// to its container so we don't need to manually add it.
// For more information, see the Fragments API guide at:
//
// http://developer.android.com/guide/components/fragments.html
//
if (savedInstanceState == null) {
// Create the detail fragment and add it to the activity
// using a fragment transaction.
Bundle arguments = new Bundle();
arguments.putInt(ItemDetailFragment.ARG_ITEM_ID,
getIntent().getIntExtra(ItemDetailFragment.ARG_ITEM_ID, 0));
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.add(R.id.item_detail_container, fragment).commit();
}
}
}
You can make the headers scroll with your view by adding the following to your code:
mGridView.setAreHeadersSticky(false);
Hope this helps.

Hide Tab from Android ActionBar

I used the application-setup thing to make a tabs layout. It uses the action bar and a ViewPager in a layout to display a number of tabs. I currently have two tabs.
However I want to add a third tab, that will be hidden unless a special button in one of the tab-fragments is pushed. On button push I thought the application could slide over to the hidden tab and make it visible. Sliding back would make it hidden again.
Is this even possible in Android as it is? :)
How would I implement this with my current form of tab-management? I found some questions like this about people using the TabActivity or TabHosts in the layout. Would it be easier with one of the two implementations?
If you need any source code just ask. Thanks in advance.
Yeah, what you're asking can be done.
In a nutshell:
In your onClickListener for the Button you've designated to make the hidden tab visible, you should call ActionBar.addTab.
Adding the new Fragment
Depending on the layout that contains your Fragments, you could call FragmentTransaction.hide and FragmentTransaction.show, but otherwise I would assume you're adding the Fragment dynamically and therefore using a FragmentPagerAdapter, in which case add your new Fragment to your List.
Links
ActionBar - addTab
FragmentTransaction - hide, show
You should also read up on the Adding Fragments docs.
Here's a very basic example:
ViewPager's Adapter
public class PagerAdapter extends FragmentPagerAdapter {
/**
* The list of {#link Fragment}s used in the adapter
*/
private final List<Fragment> mFragments = new ArrayList<Fragment>();
/**
* Constructor for <code>PagerAdapter</code>
*
* #param fm The {#link FragmentManager} to use.
*/
public PagerAdapter(FragmentManager fm) {
super(fm);
}
/**
* Adds a new {#link Fragment} to the adapter
*
* #param fragment The new {#link Fragment} to add to the list
*/
public void addFragment(Fragment fragment) {
mFragments.add(fragment);
notifyDataSetChanged();
}
/**
* {#inheritDoc}
*/
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
/**
* {#inheritDoc}
*/
#Override
public int getCount() {
return mFragments.size();
}
}
Dummy Fragment
public static final class DummyFragment extends Fragment implements View.OnClickListener {
/**
* Empty constructor as per the {#link Fragment} docs
*/
public DummyFragment() {
}
/**
* #param color The color to make the root view
* #return A new instance of {#link DummyFragment}
*/
public static DummyFragment getInstance(int color) {
final Bundle bundle = new Bundle();
bundle.putInt("color", color);
final DummyFragment fragment = new DummyFragment();
fragment.setArguments(bundle);
return fragment;
}
/**
* {#inheritDoc}
*/
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);
rootView.setBackgroundColor(getArguments().getInt("color"));
return rootView;
}
/**
* {#inheritDoc}
*/
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// This should be your Button
view.setOnClickListener(this);
}
/**
* {#inheritDoc}
*/
#Override
public void onClick(View v) {
// This adds the new tab
((MainActivity) getActivity()).addTab(2, Color.BLUE);
}
}
Called to add each Fragment
/**
* Used to add a new {#link Fragment} to {#link ViewPager}'s adapter and
* adds a new {#link Tab} to the {#link ActionBar}.
*
* #param pageTitle The title of the tab
* #param color The background color of the {#link Fragment}
*/
public void addTab(int pageTitle, int color) {
mPagerAdapter.addFragment(DummyFragment.getInstance(color));
mActionBar.addTab(mActionBar.newTab()
.setText("" + pageTitle)
.setTabListener(this));
}

Passing message from Activity to Fragment

I seem to have a problem passing data gotten in an Activity to a Fragment. The data does not appear in the listfragment!
Here is my listfragmentactivity. I reinstantiate the fragment every time I add an item to the list aka bundle an item and use the constructor in the new fragment to do it.
package com.example.sample;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
/**
* An activity representing a list of Courses. This activity has different
* presentations for handset and tablet-size devices. On handsets, the activity
* presents a list of items, which when touched, lead to a
* {#link CourseDetailActivity} representing item details. On tablets, the
* activity presents the list of items and item details side-by-side using two
* vertical panes.
* <p>
* The activity makes heavy use of fragments. The list of items is a
* {#link CourseListFragment} and the item details (if present) is a
* {#link CourseDetailFragment}.
* <p>
* This activity also implements the required
* {#link CourseListFragment.Callbacks} interface to listen for item selections.
*/
public class CourseListActivity extends SherlockFragmentActivity implements
CourseListFragment.Callbacks {
CourseListFragment listFrag;
public static String courseName;
private static final int REQUEST_CODE = 10;
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
private boolean once = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_course_list);
if (findViewById(R.id.course_detail_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
listFrag = ((CourseListFragment) getSupportFragmentManager().findFragmentById(
R.id.course_list));
listFrag.setActivateOnItemClick(true);
}
// TODO: If exposing deep links into your app, handle intents here.
}
/**
* Callback method from {#link CourseListFragment.Callbacks} indicating that
* the item with the given ID was selected.
*/
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getSupportMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
boolean bool;
switch (item.getItemId()) {
case R.id.add_course:
Intent intent = new Intent(this, CourseAddActivity.class);
startActivityForResult(intent, REQUEST_CODE);
bool = true;
default:
bool = super.onOptionsItemSelected(item);
}
return bool;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data.hasExtra("courseName")) {
courseName = data.getExtras().getString("courseName");
Bundle args = new Bundle();
args.putString("courseKey", courseName);
listFrag = new CourseListFragment(args);
}
}
}
#Override
public void onItemSelected(String id) {
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
if (once) {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// initiating both tabs and set text to it.
ActionBar.Tab assignTab = actionBar.newTab().setText(
"Assignments");
ActionBar.Tab schedTab = actionBar.newTab().setText("Schedule");
ActionBar.Tab contactTab = actionBar.newTab()
.setText("Contact");
// Create three fragments to display content
Fragment assignFragment = new Assignments();
Fragment schedFragment = new Schedule();
Fragment contactFragment = new Contact();
assignTab.setTabListener(new MyTabsListener(assignFragment));
schedTab.setTabListener(new MyTabsListener(schedFragment));
contactTab.setTabListener(new MyTabsListener(contactFragment));
actionBar.addTab(assignTab);
actionBar.addTab(schedTab);
actionBar.addTab(contactTab);
once = false;
}
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, CourseDetailActivity.class);
startActivity(detailIntent);
}
}
class MyTabsListener implements ActionBar.TabListener {
public Fragment fragment;
public MyTabsListener(Fragment fragment) {
this.fragment = fragment;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(R.id.course_detail_container, fragment);
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(fragment);
}
}
}
And here is my ListFragment, where I create two constructors, one which accepts arguments.
package com.example.sample;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockListFragment;
/**
* A list fragment representing a list of Courses. This fragment also supports
* tablet devices by allowing list items to be given an 'activated' state upon
* selection. This helps indicate which item is currently being viewed in a
* {#link CourseDetailFragment}.
* <p>
* Activities containing this fragment MUST implement the {#link Callbacks}
* interface.
*/
public class CourseListFragment extends SherlockListFragment {
private static String courseName;
ArrayList<String> courseItems;
ArrayAdapter<String> adapter;
/**
* The serialization (saved instance state) Bundle key representing the
* activated item position. Only used on tablets.
*/
private static final String STATE_ACTIVATED_POSITION = "activated_position";
/**
* The fragment's current callback object, which is notified of list item
* clicks.
*/
private Callbacks mCallbacks = sDummyCallbacks;
/**
* The current activated item position. Only used on tablets.
*/
private int mActivatedPosition = ListView.INVALID_POSITION;
/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
* selections.
*/
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(String id);
}
/**
* A dummy implementation of the {#link Callbacks} interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
#Override
public void onItemSelected(String id) {
}
};
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public CourseListFragment() {
}
public CourseListFragment(Bundle args) {
courseName = args.get("courseKey").toString();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
courseItems = new ArrayList<String>();
adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, courseItems);
// TODO: replace with a real list adapter.
int layout = (Build.VERSION.SDK_INT >= 11) ? android.R.layout.simple_list_item_activated_1
: android.R.layout.simple_list_item_1;
setListAdapter(adapter);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Restore the previously serialized activated item position.
if (savedInstanceState != null
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState
.getInt(STATE_ACTIVATED_POSITION));
courseItems.add(courseName);
adapter.notifyDataSetChanged();
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException(
"Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
#Override
public void onDetach() {
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
}
#Override
public void onListItemClick(ListView listView, View view, int position,
long id) {
super.onListItemClick(listView, view, position, id);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
// Serialize and persist the activated item position.
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
/**
* Turns on activate-on-click mode. When this mode is on, list items will be
* given the 'activated' state when touched.
*/
public void setActivateOnItemClick(boolean activateOnItemClick) {
// When setting CHOICE_MODE_SINGLE, ListView will automatically
// give items the 'activated' state when touched.
getListView().setChoiceMode(
activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
private void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
getListView().setItemChecked(mActivatedPosition, false);
} else {
getListView().setItemChecked(position, true);
}
mActivatedPosition = position;
}
}
Any help at all is much appreciated!
Thank You!
If you re-instantiate like this, class variables of CourseListFragment will be destroyed each time you call
listFrag = new CourseListFragment(args);
You should create a method in CourseListFragment to add a course name without destroying the current fragment:
public void addCourse(String courseName) {
courseItems.add(courseName);
adapter.notifyDataSetChanged();
}
And in your activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data.hasExtra("courseName")) {
courseName = data.getExtras().getString("courseName");
listFrag.addCourse(courseName);
}
}
}

Categories

Resources