PreferenceActivity -> getActionBar().setDisplayHomeAsUpEnabled giving NullPointerException - android-activity

I have some questions about a discussed topic.
I get a NullPointerException from the following code. My questions are:
Why do I get a NullPointerException ? i.e. why does getActionBar() return null ?
Request answers to be in Layman terms please.
SettingActivity.java
public class SettingsActivity extends PreferenceActivity {
/**
* Determines whether to always show the simplified settings UI, where
* settings are presented in a single list. When false, settings are shown
* as a master/detail two-pane view on tablets. When true, a single pane is
* shown on tablets.
*/
private static final boolean ALWAYS_SIMPLE_PREFS = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupActionBar();
}
/**
* Set up the {#link android.app.ActionBar}, if the API is available.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// Show the Up button in the action bar.
getSupportActionBar()
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
Style.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
build.gradle
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.android.support:support-v4:22.1.1'
}
Error
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference
at com.example.deep.sunshine.SettingsActivity.setupActionBar(SettingsActivity.java:59)
at com.example.deep.sunshine.SettingsActivity.onCreate(SettingsActivity.java:49)

Related

Set compare editor as readonly

I'm developing an Eclipse plugin, where I need every editor of the application to be readonly, depending on the path of the contained file (relative to the project).
I've made my own editor class, and been able to override some method to get what I want:
public class MyTextEditor extends TextEditor {
/**
* Overridden to inhibit the replace action in find&replace dialog.
*/
#Override
public boolean isEditorInputModifiable() {
if (!super.isEditorInputModifiable()) {
return false;
}
return Utils.checkEditorInputModifiable(getEditorInput());
}
/**
* Overridden to inhibit any user edit in the editor input.
*/
#Override
public boolean isEditable() {
if (!super.isEditable()) {
return false;
}
return Utils.checkEditorInputModifiable(getEditorInput());
}
How to make read only editor in Eclipse (Eclipse Plugin Development)
But the question is: how to do that on the compare editor??
The editor used by eclipse in each compare dialog is a different editor, I can use my content ContentMergeViewer and set the compareConfiguration as readonly (on one side or both) but this is not sufficient. The compareInput on each side should be made readonly!
Or is there any other more convenient way to achive what I want??
Thank you!
I have a possible solution: you can extend the TextMergeViewer and override some method to check the file path "on the fly":
public abstract class AbstractMergeViewer extends TextMergeViewer {
/**
* Overridden to check if the editor input is modifiable.
*
* #see {#link TextMergeViewer#setEditable(ISourceViewer sourceViewer, boolean state)}
*/
#Override
protected void setEditable(ISourceViewer sourceViewer, boolean state) {
if (!Utils.checkEditorInputModifiable(getEditorInput(sourceViewer))) {
state = false;
}
super.setEditable(sourceViewer, state);
}
/**
* Return a custom implementation of a {#link MergeViewerContentProvider},
* to check if the content is modifiable.
*/
public IContentProvider getContentProvider() {
return new MASMergeViewerContentProvider(getCompareConfiguration());
}
}
The contentProvider has to be extended too:
public class MyMergeViewerContentProvider extends MergeViewerContentProvider {
/**
* Check if the left content is modifiable, with
* {#link Utils#checkResourceModifiable}.
*
* #see org.eclipse.compare.internal.MergeViewerContentProvider#isLeftEditable(java.lang.Object)
*/
#Override
public boolean isLeftEditable(Object element) {
if (element instanceof ICompareInput) {
Object left = ((ICompareInput) element).getLeft();
if (left instanceof LocalResourceTypedElement) {
LocalResourceTypedElement res = (LocalResourceTypedElement) left;
if (!Utils.checkResourceModifiable(res.getResource())) {
return false;
}
}
}
return super.isLeftEditable(element);
}
/**
* Check if the right content is modifiable, with
* {#link Utils#checkResourceModifiable}.
*
* #see org.eclipse.compare.internal.MergeViewerContentProvider#isRightEditable(java.lang.Object)
*/
#Override
public boolean isRightEditable(Object element) {
if (element instanceof ICompareInput) {
Object right = ((ICompareInput) element).getRight();
if (right instanceof LocalResourceTypedElement) {
LocalResourceTypedElement res = (LocalResourceTypedElement) right;
if (!Utils.checkResourceModifiable(res.getResource())) {
return false;
}
}
}
return super.isRightEditable(element);
}
This way all the graphic element in the compare dialog have the right state (disabled if the file is readonly).
MergeViewerContentProvider is an internal class, and should not be extended.. but I haven't found another solution.
The MergeViewer can be applied to a contentType via the extension point
org.eclipse.compare.contentMergeViewers
Now I have another problem: if the contentType is not one that I have defined, Eclipse uses its own implementation of the compare editor, and not mine.
Should I open a new question?

how do i implement android mapbox android sdk successfully in fragment

I am using mapbox in a fragment with bottom navigation, when i exit and resume the app or when i change tabs rapidly, the app crashes. this is the error i get
10-07 22:20:36.046 21867-21886/com.dropexpress.driver.dropexpressdriver E/Mbgl-FileSource: Failed to read the storage key:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.os.Bundle.getBoolean(java.lang.String, boolean)' on a null object reference
at com.mapbox.mapboxsdk.storage.FileSource.getCachePath(FileSource.java:88)
at com.mapbox.mapboxsdk.storage.FileSource$FileDirsPathsTask.doInBackground(FileSource.java:165)
at com.mapbox.mapboxsdk.storage.FileSource$FileDirsPathsTask.doInBackground(FileSource.java:155)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
the below code always fails when i exit the app and resume, or when i change tabs rapidly, i am using bottom navigation.
Steps to reproduce
here is my fragment code
package com.dropexpress.driver.dropexpressdriver.fragments;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.dropexpress.driver.dropexpressdriver.R;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.maps.MapView;
public class HomeFragment extends Fragment {
private MapView mapView;
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public HomeFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment HomeFragment.
*/
// TODO: Rename and change types and number of parameters
public static HomeFragment newInstance(String param1, String param2) {
HomeFragment fragment = new HomeFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
Mapbox.getInstance(requireActivity(), "pk.eyJ1Ijoic3ludGF4bHRkIiwiYSI6ImNqaDJxNnhzbDAwNnMyeHF3dGlqODZsYjcifQ.pcz6BWpzCHeZ6hQg4AH9ww");
mapView = (MapView) view.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
#Override
public void onResume() {
super.onResume();
mapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mapView.onPause();
}
#Override
public void onStop() {
super.onStop();
mapView.onStop();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}
Android versions: 5.0 +
Device models: motorola g5
Mapbox SDK versions: 6.5.0
Put your Mapbox.getInstance before inflating your layout.
Mapbox.getInstance(requireActivity(),"Your Map Key");
View view = inflater.inflate(R.layout.fragment_home, container, false);
mapView = (MapView) view.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
I hope this helps you.
i opened this issue in github, you check their response here
https://github.com/mapbox/mapbox-gl-native/issues/13044#issuecomment-427861016
this was their response:
I can see 2 issues with the provided code:
You are not calling MapView#onDestroy, this has to be called from you fragment's #onDestroyView.
MapView#onCreate should be called from fragment's #onViewCreatedinstead of #onCreateView.
I applied the changes and it worked!

GWT / GWTBootstrap3 Extending Tooltip: Exception with addHandler in C'tor

I created the following class as an extension of gwtbootstrap3 Tooltip. There are at least 2 reasons why I want to derive the gwtbootstrap3 Tooltip class:
1.) Add a onWindowClosing Handler when the tooltip is shown so I can hide() the tooltip when the user leaves the page (this is - as far as I understand - a feature which is also not supported in Bootstrap, is it?)
2.) I want to prevent Tooltips from being shown when the page is displayed on iPads or iPhones as they behave strange when tooltips are involved (first tip shows the tooltip , the second tip executes the button, which is not exactly what the user expects)
Please note that the class given below is still not finished ... but already at this stage I get an exception when adding a handler.
Please also note that it throws an exception no matter what type of Handler (ShowHandler, ShownHandler, etc.) I add.
Any help greatly appreciated.
package com.mypackage.client.widgets.featureWidgets;
import org.gwtbootstrap3.client.shared.event.ShowEvent;
import org.gwtbootstrap3.client.shared.event.ShowHandler;
import org.gwtbootstrap3.client.ui.constants.Trigger;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ClosingEvent;
public class Tooltip extends org.gwtbootstrap3.client.ui.Tooltip {
private boolean isMobile;
private HandlerRegistration windowClosingHandlerRegistration;
private final Tooltip tooltip;
public Tooltip() {
super();
tooltip = this;
this.addShowHandler(new ShowHandler() {
#Override
public void onShow(final ShowEvent showEvent) {
// TODO Auto-generated method stub
if (windowClosingHandlerRegistration == null) {
windowClosingHandlerRegistration = Window.addWindowClosingHandler(new Window.ClosingHandler() {
#Override
public void onWindowClosing(final ClosingEvent arg0) {
tooltip.hide();
}
});
}
}
});
}
}
When I create a instance of this tooltip using the following:
[...]
<b:ButtonToolBar ui:field="itemButtonToolBar" addStyleNames="hiddenPrint">
<b:ButtonGroup>
<a:Tooltip title="{msgs.buttomTitleAddItem}" container="body">
<b:Button ui:field="addItemButton" icon="PLUS"/>
</a:Tooltip>
[...]
I get the following exception when trying to add the Handler, why?
SEVERE: (TypeError) : Cannot read property 'addHandler_11_g$' of undefinedcom.google.gwt.core.client.JavaScriptException: (TypeError) : Cannot read property 'addHandler_11_g$' of undefined
at Unknown.addShowHandler_2_g$(meetingApp-0.js#26:57195)
at Unknown.Tooltip_6_g$(meetingApp-0.js#8:57685)
at Unknown.build_f_Tooltip2_0_g$(meetingApp-0.js#55:31606)
at Unknown.get_f_Tooltip2_0_g$(meetingApp-0.js#15:31831)
at Unknown.build_f_ButtonGroup1_0_g$(meetingApp-0.js#38:31524)
at Unknown.get_f_ButtonGroup1_0_g$(meetingApp-0.js#15:31791)
at Unknown.build_itemButtonToolBar_0_g$(meetingApp-0.js#41:31696)
at Unknown.get_itemButtonToolBar_0_g$(meetingApp-0.js#15:31876)
at Unknown.createAndBindUi_58_g$(meetingApp-0.js#91:31437)
at Unknown.createAndBindUi_59_g$(meetingApp-0.js#15:31441)
at Unknown.ItemButtonGroup_2_g$(meetingApp-0.js#56:30733)
at Unknown.$init_589_g$(meetingApp-0.js#31:37722)
at Unknown.SummaryWidget_1_g$(meetingApp-0.js#8:37686)
at Unknown.loadSummaryWidget_0_g$(meetingApp-0.js#26:4991)
at Unknown.setSummary_1_g$(meetingApp-0.js#10:5028)
at Unknown.onSuccess_8_g$(meetingApp-0.js#21:3312)
at Unknown.onSuccess_9_g$(meetingApp-0.js#8:3317)
at Unknown.onResponseReceived_0_g$(meetingApp-0.js#26:156917)
at Unknown.fireOnResponseReceived_0_g$(meetingApp-0.js#17:129224)
at Unknown.onReadyStateChange_0_g$(meetingApp-0.js#28:129532)
at Unknown.<anonymous>(meetingApp-0.js#18:172082)
at Unknown.apply_0_g$(meetingApp-0.js#28:104636)
at Unknown.entry0_0_g$(meetingApp-0.js#16:104692)
at Unknown.<anonymous>(meetingApp-0.js#14:104672)
Disclaimer: I use gwtbootstrap3 v0.9.2 and I believe it's the same version as you use as I got the same error for your code.
A Tooltip needs a Widget to operate on (in your case the Button is a Tooltip's widget). Tooltip uses it's widget to do all events handling - see source code for addShowHandler for example.
Now you need to understand how the whole structure is built:
first the Tooltip is created (wit no widget set)
then the Button is created
Tooltip's setWidget method is called to set the button as a widget
So when you use addShowHandler method in your constructor, you actually call widget.addHandler while widget is null.
You can check it by Window.alert(tooltip.getWidget() == null ? "null" : tooltip.getWidget().toString());
There are few ways to make it work (the later the better):
wait for DOM structure to be built by scheduling a deferred command (if you are sure that the widget will be eventually set):
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
// set up events handling
}
});
override setWidget method (note thet there are two methods: setWidget(Widget w) and setWidget(IsWidget w)):
#Override
public void setWidget(Widget w) {
super.setWidget(w);
// set up events handling
}
you don't need to addWindowClosingHandler in the showEvent handler, you can do it directly in the constructor:
public class Tooltip extends org.gwtbootstrap3.client.ui.Tooltip {
private boolean isMobile;
private final Tooltip tooltip;
public Tooltip() {
super();
tooltip = this;
Window.addWindowClosingHandler(new Window.ClosingHandler() {
#Override
public void onWindowClosing(final ClosingEvent arg0) {
tooltip.hide();
}
});
}
}

onLongClick with Context Action Bar CAB not taking place, only onListItemClick performed, in tablet activity with ListFragment and DetailFragment

I have a ListFragment that is called from a ListActivity, with a dual fragment layout on a tablet.
I have used the standard MasterDetail Fragment setup from Android Studio 0.3.6 API 19.
MyListFragment looks as follows:
import android.app.Activity;
import android.content.ContentUris;
import android.net.Uri;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.support.v4.widget.SimpleCursorAdapter;
import com.supascale.supascale.contentprovider.SupaScaleContentProvider;
import com.supascale.supascale.database.SupascaleDb;
/**
* A list fragment representing a list of Animals. 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 AnimalDetailFragment}.
* <p>
* Activities containing this fragment MUST implement the {#link Callbacks}
* interface.
*
* You can create new ones via the ActionBar entry "Insert".
* You can delete existing ones via a long press on the item.
*/
public class AnimalListFragment extends ListFragment implements
android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor>{
private static final int ACTIVITY_CREATE = 0;
private static final int ACTIVITY_EDIT = 1;
private static final int DELETE_ID = Menu.FIRST + 1;
private SimpleCursorAdapter adapter;
protected Object mActionMode;
private ActionMode.Callback mActionModeCallback;
/**
* 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. NB AJW
*/
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(Uri 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(Uri animalUri) {
}
};
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public AnimalListFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
return inflater.inflate(R.layout.animal_list, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
String[] from = new String[] { SupascaleDb.KEY_Animal_ANIMALIDENTIFICATION };
// Fields on the UI to which we map
int[] to = new int[] { R.id.label };
getLoaderManager().initLoader(0, null, this);
adapter = new SimpleCursorAdapter(getActivity(), R.layout.animal_row, null, from,
to, 0);
setListAdapter(adapter);
// Restore the previously serialized activated item position.
if (savedInstanceState != null
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
}
mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.listmenu, menu);
return true;
}
// Called each time the action mode is shown. Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case DELETE_ID:
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
.getMenuInfo();
Uri uri = Uri.parse(SupaScaleContentProvider.CONTENT_URI_ANIMAL + "/"
+ info.id);
getActivity().getContentResolver().delete(uri, null, null);
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
getView().setOnLongClickListener( new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
if (mActionMode != null) {
return false;
}
// Start the CAB using the ActionMode.Callback defined above
mActionMode = view.startActionMode(mActionModeCallback);
view.setSelected(true);
return true;
}
});
}
#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.
//2013-11-26 AJW Append the clicked item's row ID with the content provider Uri
Uri animalUri = ContentUris.withAppendedId(SupaScaleContentProvider.CONTENT_URI_ANIMAL, id);
// Send the event and Uri to the host activity
mCallbacks.onItemSelected(animalUri);
}
#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;
}
/**
* Creates a new loader after the initLoader () call
*/
//#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { SupascaleDb.KEY_ROWID, SupascaleDb.KEY_Animal_ANIMALIDENTIFICATION };
CursorLoader cursorLoader = new CursorLoader(getActivity(),
SupaScaleContentProvider.CONTENT_URI_ANIMAL, projection, null, null, null);
return cursorLoader;
}
//#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
//#Override
public void onLoaderReset(Loader<Cursor> loader) {
// data is not available anymore, delete reference
adapter.swapCursor(null);
}
}
My AnimalListActivity looks as follows:
/**
* An activity representing a list of Animals. 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 AnimalDetailActivity} 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 AnimalListFragment} and the item details
* (if present) is a {#link AnimalDetailFragment}.
* <p>
* This activity also implements the required
* {#link AnimalListFragment.Callbacks} interface
* to listen for item selections.
*/
public class AnimalListActivity extends FragmentActivity
implements AnimalListFragment.Callbacks {
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
private SimpleCursorAdapter adapter;
private static final int ACTIVITY_CREATE = 0;
private static final int ACTIVITY_EDIT = 1;
private static final int DELETE_ID = Menu.FIRST + 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animal_list);
if (findViewById(R.id.animal_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.
((AnimalListFragment) getSupportFragmentManager()
.findFragmentById(R.id.animal_list))
.setActivateOnItemClick(true);
}
// TODO: If exposing deep links into your app, handle intents here.
}
/**
* Callback method from {#link AnimalListFragment.Callbacks}
* indicating that the item with the given ID was selected.
*/
#Override
public void onItemSelected(Uri animalUri) {
//String id = Long.toString(ContentUris.parseId(animalUri));
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(AnimalDetailFragment.ARG_URI, animalUri.toString()); //Key value pair Adrian "animal_uri = .."
AnimalDetailFragment fragment = new AnimalDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.animal_detail_container, fragment)
.commit();
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, AnimalDetailActivity.class);
//Uri todoUri = Uri.parse(SupaScaleContentProvider.CONTENT_URI_ANIMAL + "/" + id);
//detailIntent.putExtra(AnimalDetailFragment.ARG_ITEM_ID, id);
//startActivity(detailIntent);
detailIntent.putExtra(SupaScaleContentProvider.CONTENT_ITEM_TYPE, animalUri);
// Activity returns an result if called with startActivityForResult
startActivityForResult(detailIntent, ACTIVITY_EDIT);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.listmenu, menu);
return true;
}
// Reaction to the menu selection
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.insert:
createAnimal();
return true;
}
return super.onOptionsItemSelected(item);
}
private void createAnimal() {
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(AnimalDetailFragment.ARG_URI, animalUri.toString()); //Key value pair Adrian "animal_uri = .."
AnimalDetailFragment fragment = new AnimalDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.animal_detail_container, fragment)
.commit();
} else {
// In single-pane mode, simply start the detail activity
Intent i = new Intent(this, AnimalDetailActivity.class);
startActivityForResult(i, ACTIVITY_EDIT);
}
}
}
AnimalListActivity.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/animal_list"
android:name="com.supascale.supascale.AnimalListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
tools:context=".AnimalListActivity"
tools:layout="#android:layout/list_content" />
The List.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#android:id/list" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Animal Data"
android:id="#android:id/empty" />
</LinearLayout>
The row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/icon"
android:layout_width="30dp"
android:layout_height="24dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:src="#drawable/reminder" >
</ImageView>
<TextView
android:id="#+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:lines="1"
android:text="#+id/textViewNormalTotal"
android:textSize="24sp"
>
</TextView>
</LinearLayout>
The fragment list scrolls correctly, and when clicked the detail fragment is correctly populated. When I long click, nothing happens, and when I release the longclick, the click event is fired.
I need for the long click to result in the CAB (Context Action Bar) to display, so that I can delete a record, or share a record etc.
mActionMode = view.startActionMode(mActionModeCallback); just never appears to be called.
Hope I have been clear enough.
Regards
Adrian
I edited and added the imports for the ListFragment, as it may have to do with support.v4?
Ok, so I did not understand the CAB help so nicely.
http://developer.android.com/guide/topics/ui/menus.html#CAB
For a ListView or ListFragment, and not another kind of view, you must use the setOnItemLongClickListener,
and not the setOnLongClickListener, as in the help from developer.android.com.
The setOnLongClickListener, is never activated by the listview, and thus never can procede to create the CAB.
I removed the following code:
getView().setOnLongClickListener( new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
if (mActionMode != null) {
return false;
}
// Start the CAB using the ActionMode.Callback defined above
mActionMode = view.startActionMode(mActionModeCallback);
view.setSelected(true);
return true;
}
});
and replaced with the following:
getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int position, long id) {
if (mActionMode != null) {
return false;
}
Animal_id = id;
// Start the CAB using the ActionMode.Callback defined above
mActionMode = getActivity().startActionMode(mActionModeCallback);
view.setSelected(true);
return true;
}
});
Now the long click event fires, and I can get the CAB to display properly.

Preference Screen options (CheckBoxPreference and EditTextPreference) is not showing

I am new to android. My Preference Screen option is not showing. I am following below tutorial section "Preferences" and "Creating the Settings Activity"(https://wiki.oulu.fi/display/esde/List+views%2C+Intents%2C+Preferences+and+Notifications)
This is my SettingsActivity.java class
public class SettingsActivity extends Activity {
public static class SettingsFragment extends PreferenceFragment {
private SettingsFragment settingsFragment = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
settingsFragment = new SettingsFragment();
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, settingsFragment)
.commit();
}
}
This is the settings for Preference
<?xml version="1.0" encoding="utf-8"?>
<PreferenceCategory android:title="#string/server_settings" >
</PreferenceCategory>
<CheckBoxPreference
android:defaultValue="false"
android:key="#+id/pref_check"
android:summaryOff="#string/pref_off"
android:summaryOn="#string/pref_on" >
</CheckBoxPreference>
<EditTextPreference
android:key="#+id/pref_edit"
android:defaultValue="#string/pref_default"
android:dialogTitle="#string/edit_text_pref">
</EditTextPreference>
In the main activity I have below method for launching SettingActivity class.
// launch the settings activity
public boolean onOptionsItemSelected(MenuItem item) {
startActivity(new Intent(this, SettingsActivity.class));
//return super.onOptionsItemSelected(item);
return true;
}
Also I have added below code under main activity, onCreate method to initialize the default values for the settings, from the preferences setting file
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
Could you help me on this issue?