I have a fragment with a relative layout - which is correctly displayed.
Now I try to add a custom view with canvas - where I can dynamically draw on. But the onDraw-method of the custom view is not called if I call the drawConnectionLine method from the custom View. If I do not call the drawConnectionLine method it works.
I tried to call the drawConnectionLine in the onResume-method after the view is created but it does not help...
How can I dynamically draw on the custom view after initialization without a NullPointerException(because of the onDraw not being executed)?
Here is my fragment-code(FragmentPlan.java):
package de.tucais.svm.youplan;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import android.app.Activity;
import android.app.Fragment;
import android.content.ContentValues;
import android.graphics.Canvas;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class FragmentPlan extends Fragment
{
// Define logging variables
private static final String LOGCAT = "YP-FragmentPlan";
private static final boolean D = true; // control debug-output
Activity parentActivity;
LibSVM svm = null;
DatabaseController db;
Controller controller = null;
DrawView drawView = null;
//Canvas drawCanvas = null;
int firstTv_margin_top, firstTv_margin_left, firstTv_margin_right, firstTv_margin_bottom;
int tv_margin_top, tv_margin_left, tv_margin_right, tv_margin_bottom;
RelativeLayout planLayout = null;
List<TextView> taskElements = new ArrayList<TextView>();
public FragmentPlan()
{
}
public void onResume()
{
super.onResume();
computeResult();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_plan, container, false);
controller = new Controller((MainActivity)getActivity());
planLayout = (RelativeLayout)view.findViewById(R.id.relativeLayout_plan);
// Translate the margin-values from dp to pixel
firstTv_margin_left = getResources().getDimensionPixelSize(R.dimen.plan_firstTv_margin_left);
firstTv_margin_top = getResources().getDimensionPixelSize(R.dimen.plan_firstTv_margin_top);
firstTv_margin_right = getResources().getDimensionPixelSize(R.dimen.plan_firstTv_margin_right);
firstTv_margin_bottom = getResources().getDimensionPixelSize(R.dimen.plan_firstTv_margin_bottom);
tv_margin_left = getResources().getDimensionPixelSize(R.dimen.plan_tv_margin_left);
tv_margin_top = getResources().getDimensionPixelSize(R.dimen.plan_tv_margin_top);
tv_margin_right = getResources().getDimensionPixelSize(R.dimen.plan_tv_margin_right);
tv_margin_bottom = getResources().getDimensionPixelSize(R.dimen.plan_tv_margin_bottom);
// Create the DrawView and append it to the RelativeLayout
drawView = new DrawView((MainActivity)getActivity());
RelativeLayout.LayoutParams drawViewParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
drawView.setLayoutParams(drawViewParams);
drawView.setId(View.generateViewId());
planLayout.addView(drawView);
//sendViewToBack(drawView);
if(D) Log.i(LOGCAT,"drawCanvas created...");
if(D) Log.i(LOGCAT,"onCreateView finished...");
return view;
}
private void computeResult()
{
List<ContentValues> result = controller.computeSequence();
//displayResult(result.get(0));
for(int i=0; i < result.size(); i++)
{
displayResultElement(result.get(i));
if(i > 0)
{
if(D) Log.i(LOGCAT,"tried to draw connection for " + i + " time...");
if(D) Log.i(LOGCAT,"DrawCanvas is null: " + drawView.isCanvasNull()); //-> returns true
drawView.drawConnectionLine(taskElements, i); //-> this call causes the error
if(D) Log.i(LOGCAT,"succesfully drawed connection nr" + i + "...");
}
}
}
private void displayResultElement(ContentValues resultElement)
{
// Create a new element
TextView newElement = new TextView((MainActivity)getActivity());
newElement.setId(View.generateViewId());
newElement.setBackground(getResources().getDrawable(R.drawable.shape_circle));
// Fill the new Element with its content
Set<Entry<String, Object>> s = resultElement.valueSet();
Iterator<Entry<String, Object>> itr = s.iterator();
Map.Entry<String, Object> me = (Map.Entry<String, Object>)itr.next();
newElement.append(me.getKey().toString()+": " + me.getValue().toString());
while(itr.hasNext())
{
me = (Map.Entry<String, Object>)itr.next();
newElement.append("\n"+me.getKey().toString()+": " + me.getValue().toString());
}
// After filling the new element with content append it to its parent view element
planLayout.addView(newElement);
// add the element to the list
taskElements.add(newElement);
// Position the new element on the screen
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)newElement.getLayoutParams();
// if there is more than the current element in the list position relative to the predecessor
if(taskElements.size() > 1)
{
params.addRule(RelativeLayout.BELOW, taskElements.get(taskElements.size()-2).getId());
params.addRule(RelativeLayout.ALIGN_LEFT, taskElements.get(taskElements.size()-2).getId());
params.setMargins(tv_margin_left, tv_margin_top, tv_margin_right, tv_margin_bottom);
}
else
{
params.setMargins(firstTv_margin_left, firstTv_margin_top, firstTv_margin_right, firstTv_margin_bottom);
}
newElement.setLayoutParams(params);
}
private static void sendViewToBack(final View v)
{
final ViewGroup parent = (ViewGroup)v.getParent();
if (parent != null)
{
parent.removeView(v);
parent.addView(v, 0);
}
}
}
This is my xml-file for the relativeLayout(fragment_plan.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/relativeLayout_plan"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp"
tools:context=".MainActivity" >
</RelativeLayout>
Here is my CustomView(DrawView.java):
package de.tucais.svm.youplan;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class DrawView extends View
{
// Define logging variables
private static final String LOGCAT = "YP-DrawView";
private static final boolean D = true; // control debug-output
private Canvas drawCanvas = null;
public DrawView(final Context context)
{
super(context);
if(D) Log.i(LOGCAT,"DrawView constructor called... ");
}
#Override
protected void onMeasure(int w, int h)
{
if(D) Log.d(LOGCAT,"onMeasure with w= " + w + " and h= " + h + " called...");
setMeasuredDimension(w, h);
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if(D) Log.i(LOGCAT,"onDraw called... ");
this.drawCanvas = canvas;
if(D) Log.d(LOGCAT,"drawCanvas still empty? " + (this.drawCanvas == null));
}
/*
* Method which draws a connection line between two graphical elements on the screen
* #param {List<TextView>} taskElements - a list of all TextView-elements
* #param {int} nr - the number of the destination element
*/
public void drawConnectionLine(List<TextView> taskElements, int nr)
{
if(D) Log.i(LOGCAT,"drawConnectionLine called... ");
TextView currentElement = taskElements.get(nr);
TextView prevElement = null;
try
{
prevElement = taskElements.get(nr-1);
}
catch(Exception e)
{
Log.e(LOGCAT, "No predacessor!!!");
}
int startX = computeCenter(prevElement);
int startY = prevElement.getBottom();
int stopX = computeCenter(currentElement);
int stopY = currentElement.getTop();
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
this.drawCanvas.drawLine(startX, startY, stopX, stopY, paint); //-> this.drawCanvas == null => Why???
}
private int computeCenter(View element)
{
int result = 0;
if(element != null)
{
int right = element.getRight();
result = right - (element.getWidth()/2);
}
return result;
}
public void emptyCanvas()
{
// Clear the canvas
this.drawCanvas.drawColor(Color.TRANSPARENT);
}
public boolean isCanvasNull()
{
return this.drawCanvas == null;
}
}
It would be very nice, if someone can explain me, why the onDraw-method of the DrawView is not called when calling the drawConnectionLine method- the reason for a NullPointerException in the FragmentPlan.java line 95.
Thanks in advance!!!
Yeah it seems like system assumes the view width and height to be zero and thus did not called on onDraw(). You can override the onMeasure(int, int) method in View class to specify the width and height of your view.
Link:
Custom onDraw() method not called
Related
I built a view that contains a EditText as a submit button, therefore it's not focusable in touch mode, the text is centered and it has a background color. Then, I created a fragment with this button.
When this fragment is the first one to be placed in the container to be drawn, the text is centered in the edit text as expected. However, if use an click event to replace this fragment with another fragment that contains it's own submit button, the text is not centered, let alone aligned to the left or to the right. It's not aligned at all.
After put a Hander to add a delay for requesting the layout after 5ms where I create view to be placed in the fragment, the text get centered properly. I realize that for some reason the fragment transaction is needing an extra call for requestLayout.
I isolated the code that is causing the problem. By doing this I realized that the problem is somehow related with the way I handle typefaces in my TestTextField.java. I pasted right bellow.
What could be possibly causing that? Why? If it is something wrong with my code, why it works to the first fragment I placed in the screen, but it does not work with the other ones?
TestActivity.java
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import java.lang.reflect.Method;
/**
* Created by eduardoj on 2017-07-19.
*/
public class TestActivity extends Activity
implements TestFragmentA.Listener, TestFragmentB.Listener {
private FrameLayout fragmentContainer;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewGroup.LayoutParams matchParent = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
fragmentContainer = new FrameLayout(this);
fragmentContainer.setId(View.generateViewId());
fragmentContainer.setLayoutParams(matchParent);
fragmentContainer.setFocusableInTouchMode(true);
setContentView(fragmentContainer);
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(fragmentContainer.getId(), TestFragmentA.newInstance());
transaction.commit();
}
#Override
public void onASubmitButtonClick() {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(fragmentContainer.getId(), TestFragmentB.newInstance());
transaction.commit();
}
#Override
public void onBSubmitButtonClick() {
}
}
TestFragmentA.java
import android.app.Fragment;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
/**
* Created by eduardoj on 2017-07-19.
*/
public class TestFragmentA extends Fragment {
public interface Listener {
void onASubmitButtonClick();
}
private Listener listener;
public static TestFragmentA newInstance() {
Bundle args = new Bundle();
TestFragmentA fragment = new TestFragmentA();
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
/*
* This makes sure that the container context has implemented the
* callback interface. If not, it throws an exception.
*/
try {
listener = (Listener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement TestFragmentA.Listener");
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
FrameLayout layout = new FrameLayout(getActivity());
layout.setId(View.generateViewId());
layout.setLayoutParams(params);
layout.setBackgroundColor(Color.CYAN);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
600,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER
);
TestTextField view = new TestTextField(getActivity());
view.setId(View.generateViewId());
view.setLayoutParams(lp);
view.setText("Submit A");
view.setBackgroundColor(Color.MAGENTA);
view.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
view.setEnableTextEditing(false);
view.addListener(new TestTextField.Listener() {
#Override
protected void onClick(TestTextField textField, String text) {
super.onClick(textField, text);
listener.onASubmitButtonClick();
}
});
layout.addView(view);
return layout;
}
}
TestFragmentB.java
import android.app.Fragment;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
/**
* Created by eduardoj on 2017-07-19.
*/
public class TestFragmentB extends Fragment {
public interface Listener {
void onBSubmitButtonClick();
}
private Listener listener;
public static TestFragmentB newInstance() {
Bundle args = new Bundle();
TestFragmentB fragment = new TestFragmentB();
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
/*
* This makes sure that the container context has implemented the
* callback interface. If not, it throws an exception.
*/
try {
listener = (Listener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement TestFragmentA.Listener");
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
FrameLayout layout = new FrameLayout(getActivity());
layout.setId(View.generateViewId());
layout.setLayoutParams(params);
layout.setBackgroundColor(Color.LTGRAY);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
600,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER
);
TestTextField view = new TestTextField(getActivity());
view.setId(View.generateViewId());
view.setLayoutParams(lp);
view.setText("Submit B");
view.setBackgroundColor(Color.MAGENTA);
view.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
view.setEnableTextEditing(false);
view.addListener(new TestTextField.Listener() {
#Override
protected void onClick(TestTextField textField, String text) {
super.onClick(textField, text);
listener.onBSubmitButtonClick();
}
});
layout.addView(view);
return layout;
}
}
TestTextField.java
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Handler;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
/*
* Created by eduardoj on 2017-07-13.
*/
public class TestTextField extends LinearLayout {
public static class Listener {
protected void onClick(TestTextField textField, String text) {}
}
private int BACKGROUND_COLOR = Color.MAGENTA;
private String HINT = "Enter text here";
private boolean isToUpdateMinHeight;
private EditText editText;
private Typeface textTypeface;
private Typeface hintTypeface;
private List<Listener> listeners;
public TestTextField(Context context) {
super(context);
listeners = new ArrayList<>();
/* Initializing text field */
initView();
bindListeners();
}
public void addListener(Listener listener) {
if (listener != null) {
listeners.add(listener);
}
}
public void setEnableTextEditing(boolean enable) {
editText.setFocusableInTouchMode(enable);
}
public void setHintTypeface(Typeface typeface) {
hintTypeface = typeface;
isToUpdateMinHeight = true;
updateTypeface();
}
public void setText(CharSequence text) {
editText.setText(text);
updateTypeface();
}
#Override
public void setTextAlignment(int textAlignment) {
editText.setTextAlignment(textAlignment);
}
public void setTypeface(Typeface typeface) {
isToUpdateMinHeight = true;
textTypeface = typeface;
updateTypeface();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
updateMinHeight();
}
private void initView() {
setOrientation(HORIZONTAL);
LayoutParams params = new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1);
editText = new EditText(getContext());
editText.setId(generateViewId());
editText.setLayoutParams(params);
editText.setHint(HINT);
editText.setBackgroundColor(Color.TRANSPARENT); // Removes underline
addView(editText);
updateTypeface();
setBackgroundColor(BACKGROUND_COLOR);
// Custom Typefaces: you have to set the custom typeset to reproduce the problem.
// setTypeface(G.Font.getVegurRegular(getContext()));
// setHintTypeface(G.Font.getVegurLight(getContext()));
/* This is the current work around for this Issue */
(new Handler()).postDelayed(new Runnable() {
#Override
public void run() {
requestLayout();
}
}, 15);
}
private void bindListeners() {
final TestTextField textFieldInstance = this;
editText.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
for (Listener listener : listeners) {
listener.onClick(
textFieldInstance,
editText.getText().toString()
);
}
}
});
}
/**
* Updates the minimum height to the size of the considering the biggest
* typeface.
*/
private void updateMinHeight() {
if (!isToUpdateMinHeight) {
return;
}
Typeface original = editText.getTypeface();
editText.setTypeface(textTypeface);
editText.measure(0, 0);
int textHeight = editText.getMeasuredHeight();
editText.setTypeface(hintTypeface);
editText.measure(0, 0);
int hintHeight = editText.getMeasuredHeight();
int minHeight = textHeight > hintHeight ? textHeight : hintHeight;
editText.setMinimumHeight(minHeight);
editText.setTypeface(original);
isToUpdateMinHeight = false;
}
private void updateTypeface() {
boolean hasText = editText.length() > 0;
Typeface typeface = hasText ? textTypeface : hintTypeface;
editText.setTypeface(typeface);
}
}
I came to a solution that doesn't require to call an extra requestLayout, I believe this is the right way to solve this problem.
updateMinHeight and super.onMeasure are in the wrong order in the onMeasure method. The correct way is:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
updateMinHeight();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
For me, this order above makes sense since updateMinHeight can actually change the measured size of the widget. Though this answer shows how to solve, I can't understand why the problem happens and how would this affect only the text position in very specific cases, such as to the first fragment displayed.
I want to use Identify Task in ARCGIS API for android.I used this example and it works fine but when I try to change the URL to get data from another WMS it shows error
here is my another wms
I get error in folowing line
for (int index = 0; index < results.length; index++) {
result_1 = results[index];
String displayFieldName = result_1.getDisplayFieldName();
Map<String, Object> attr = result_1.getAttributes();
for (String key : attr.keySet()) {
if (key.equalsIgnoreCase(displayFieldName)) {
resultList.add(result_1);
}
}
}
in this class which I have got from example
package com.esri.arcgis.android.samples.identifytask;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.esri.android.action.IdentifyResultSpinner;
import com.esri.android.action.IdentifyResultSpinnerAdapter;
import com.esri.android.map.Callout;
import com.esri.android.map.MapView;
import com.esri.android.map.ags.ArcGISTiledMapServiceLayer;
import com.esri.android.map.event.OnSingleTapListener;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Point;
import com.esri.core.tasks.identify.IdentifyParameters;
import com.esri.core.tasks.identify.IdentifyResult;
import com.esri.core.tasks.identify.IdentifyTask;
/**
* This sample allows the user to identify data based on single tap and view the
* results in a callout window which has a spinner in its layout. Also the user
* can select any of the results displayed and view its details. The details are
* the attribute values.
*
* The output value shown in the spinner is the display field.
*
*/
public class Identify extends Activity {
// create ArcGIS objects
MapView mMapView = null;
IdentifyParameters params = null;
// create UI objects
static ProgressDialog dialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Retrieve the map and initial extent from XML layout
mMapView = (MapView) findViewById(R.id.map);
// add demographic layer to the map
mMapView.addLayer(new ArcGISTiledMapServiceLayer(this.getResources()
.getString(R.string.identify_task_url_for_avghouseholdsize)));
// set Identify Parameters
params = new IdentifyParameters();
params.setTolerance(20);
params.setDPI(98);
params.setLayers(new int[] { 4 });
params.setLayerMode(IdentifyParameters.ALL_LAYERS);
// Identify on single tap of map
mMapView.setOnSingleTapListener(new OnSingleTapListener() {
private static final long serialVersionUID = 1L;
#Override
public void onSingleTap(final float x, final float y) {
if (!mMapView.isLoaded()) {
return;
}
// Add to Identify Parameters based on tapped location
Point identifyPoint = mMapView.toMapPoint(x, y);
params.setGeometry(identifyPoint);
params.setSpatialReference(mMapView.getSpatialReference());
params.setMapHeight(mMapView.getHeight());
params.setMapWidth(mMapView.getWidth());
params.setReturnGeometry(false);
// add the area of extent to identify parameters
Envelope env = new Envelope();
mMapView.getExtent().queryEnvelope(env);
params.setMapExtent(env);
// execute the identify task off UI thread
MyIdentifyTask mTask = new MyIdentifyTask(identifyPoint);
mTask.execute(params);
}
});
}
private ViewGroup createIdentifyContent(final List<IdentifyResult> results) {
// create a new LinearLayout in application context
LinearLayout layout = new LinearLayout(this);
// view height and widthwrap content
layout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
// default orientation
layout.setOrientation(LinearLayout.HORIZONTAL);
// Spinner to hold the results of an identify operation
IdentifyResultSpinner spinner = new IdentifyResultSpinner(this, results);
// make view clickable
spinner.setClickable(false);
spinner.canScrollHorizontally(BIND_ADJUST_WITH_ACTIVITY);
// MyIdentifyAdapter creates a bridge between spinner and it's data
MyIdentifyAdapter adapter = new MyIdentifyAdapter(this, results);
spinner.setAdapter(adapter);
spinner.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
layout.addView(spinner);
return layout;
}
/**
* This class allows the user to customize the string shown in the callout.
* By default its the display field name.
*
* A spinner adapter defines two different views; one that shows the data in
* the spinner itself and one that shows the data in the drop down list when
* spinner is pressed.
*
*/
public class MyIdentifyAdapter extends IdentifyResultSpinnerAdapter {
String m_show = null;
List<IdentifyResult> resultList;
int currentDataViewed = -1;
Context m_context;
public MyIdentifyAdapter(Context context, List<IdentifyResult> results) {
super(context, results);
this.resultList = results;
this.m_context = context;
}
// Get a TextView that displays identify results in the callout.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String LSP = System.getProperty("line.separator");
StringBuilder outputVal = new StringBuilder();
// Resource Object to access the Resource fields
Resources res = getResources();
// Get Name attribute from identify results
IdentifyResult curResult = this.resultList.get(position);
if (curResult.getAttributes().containsKey(
res.getString(R.string.NAME))) {
outputVal.append("Place: "
+ curResult.getAttributes()
.get(res.getString(R.string.NAME)).toString());
outputVal.append(LSP);
}
if (curResult.getAttributes().containsKey(
res.getString(R.string.ID))) {
outputVal.append("State ID: "
+ curResult.getAttributes()
.get(res.getString(R.string.ID)).toString());
outputVal.append(LSP);
}
if (curResult.getAttributes().containsKey(
res.getString(R.string.ST_ABBREV))) {
outputVal.append("Abbreviation: "
+ curResult.getAttributes()
.get(res.getString(R.string.ST_ABBREV))
.toString());
outputVal.append(LSP);
}
if (curResult.getAttributes().containsKey(
res.getString(R.string.TOTPOP_CY))) {
outputVal.append("Population: "
+ curResult.getAttributes()
.get(res.getString(R.string.TOTPOP_CY))
.toString());
outputVal.append(LSP);
}
if (curResult.getAttributes().containsKey(
res.getString(R.string.LANDAREA))) {
outputVal.append("Area: "
+ curResult.getAttributes()
.get(res.getString(R.string.LANDAREA))
.toString());
outputVal.append(LSP);
}
// Create a TextView to write identify results
TextView txtView;
txtView = new TextView(this.m_context);
txtView.setText(outputVal);
txtView.setTextColor(Color.BLACK);
txtView.setLayoutParams(new ListView.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
txtView.setGravity(Gravity.CENTER_VERTICAL);
return txtView;
}
}
#Override
protected void onPause() {
super.onPause();
mMapView.pause();
}
#Override
protected void onResume() {
super.onResume();
mMapView.unpause();
}
private class MyIdentifyTask extends
AsyncTask<IdentifyParameters, Void, IdentifyResult[]> {
IdentifyTask task = new IdentifyTask(Identify.this.getResources()
.getString(R.string.identify_task_url_for_avghouseholdsize));
IdentifyResult[] M_Result;
Point mAnchor;
MyIdentifyTask(Point anchorPoint) {
mAnchor = anchorPoint;
}
#Override
protected void onPreExecute() {
// create dialog while working off UI thread
dialog = ProgressDialog.show(Identify.this, "Identify Task",
"Identify query ...");
}
protected IdentifyResult[] doInBackground(IdentifyParameters... params) {
// check that you have the identify parameters
if (params != null && params.length > 0) {
IdentifyParameters mParams = params[0];
try {
// Run IdentifyTask with Identify Parameters
M_Result = task.execute(mParams);
} catch (Exception e) {
e.printStackTrace();
}
}
return M_Result;
}
#Override
protected void onPostExecute(IdentifyResult[] results) {
// dismiss dialog
if (dialog.isShowing()) {
dialog.dismiss();
}
ArrayList<IdentifyResult> resultList = new ArrayList<IdentifyResult>();
IdentifyResult result_1;
for (int index = 0; index < results.length; index++) {
result_1 = results[index];
String displayFieldName = result_1.getDisplayFieldName();
Map<String, Object> attr = result_1.getAttributes();
for (String key : attr.keySet()) {
if (key.equalsIgnoreCase(displayFieldName)) {
resultList.add(result_1);
}
}
}
Callout callout = mMapView.getCallout();
callout.setContent(createIdentifyContent(resultList));
callout.show(mAnchor);
}
}
}
and this is error
06-11 19:01:21.384 18989-18989/com.tehranuni.hazard.hazard E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.tehranuni.hazard.hazard, PID: 18989
java.lang.NullPointerException: Attempt to get length of null array
at com.tehranuni.hazard.hazard.gatter_geo_data$MyIdentifyTask.onPostExecute(gatter_geo_data.java:714)
at com.tehranuni.hazard.hazard.gatter_geo_data$MyIdentifyTask.onPostExecute(gatter_geo_data.java:661)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5321)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:117)
As the error say results is null and I think it is because it does not get fields from WMS layer.What so you think about this error?Is there any way to fix it?
Thank you so much for your help
IdentifyTask works only with an ArcGIS Server map service, not a WMS.
I am developing Horizontal Scrolling pages and tabs
MY app is working well in all devices in foreground, but when it goes to background, after one hour, the logs saying that Process com.example.myapp has died. When i reopen the app , the gridview data is not appearing but when scrolling horizontally , getView() method displaying all data like images and text.
that means app has data but view is not formed when process has died. And if i press back button and re-open the app, It is working good
My MainActivity.java is here
package com.bbgusa.bbgdemo.ui.phone;
import java.util.List;
import java.util.Vector;
import org.json.JSONObject;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TabHost;
import com.bbgusa.bbgdemo.R;
import com.bbgusa.bbgdemo.listener.phone.CustomViewPager;
import com.bbgusa.bbgdemo.ui.chat.phone.ChatFragmentTab;
import com.bbgusa.bbgdemo.ui.dialpad.phone.DialerFragment;
import com.bbgusa.bbgdemo.ui.home.phone.AlarmFragmentPhone;
import com.bbgusa.bbgdemo.ui.home.phone.HomeFragment;
import com.bbgusa.bbgdemo.ui.home.phone.HomeFragmentTab;
import com.bbgusa.bbgdemo.ui.home.phone.InfoFragPhone;
import com.bbgusa.bbgdemo.ui.home.phone.MapPhone;
import com.bbgusa.bbgdemo.ui.home.phone.WeatherFragmentPhone;
import com.bbgusa.bbgdemo.ui.messages.phone.MessagesFragment;
import com.bbgusa.bbgdemo.ui.settings.phone.AboutFragment;
import com.bbgusa.bbgdemo.ui.tablet.ConstantsManager;
import com.bbgusa.bbgdemo.ui.tablet.OnFragmentChangedListenerPhone;
import com.bbgusa.bbgdemo.utils.common.UConnectUtils;
public class MainActivity extends FragmentActivity implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener, OnFragmentChangedListenerPhone {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_phone);
this.initialiseTabHost(savedInstanceState);
initialiseViewPager();
}
/**
* Initialise ViewPager
*/
private void initialiseViewPager() {
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this,HomeFragmentTab.class.getName()));
fragments.add(Fragment.instantiate(this, DialerFragment.class.getName()));
fragments.add(Fragment.instantiate(this,MessagesFragment.class.getName()));
fragments.add(Fragment.instantiate(this,ChatFragmentTab.class.getName()));
fragments.add(Fragment.instantiate(this, AboutFragment.class.getName()));
this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);
this.mViewPager = (CustomViewPager) findViewById(R.id.tabviewpager);
this.mViewPager.setAdapter(this.mPagerAdapter);
this.mViewPager.setOnPageChangeListener(this);
this.mViewPager.setOffscreenPageLimit(5);
this.mViewPager.setCurrentItem(0);
}
#Override
public void onFragmentChangePhone(JSONObject response, String whichView, String title, String mPhoneNo) {
Bundle b = new Bundle();
if(response != null)
b.putString("JSONObject", response.toString());
if(title != null)
b.putString("Title", title);
String propertyId = UConnectUtils.getPropertyId(mPref, getString(R.string.property_id));
b.putString(UConnectUtils.PROPERTY_ID_KEY, propertyId);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
Fragment fragment = null;
if (whichView.equals(ConstantsManager.GRIDVIEWPAGER)) {
// getSupportFragmentManager().popBackStack();
fragment = new HomeFragment();
} else if (whichView.equals(ConstantsManager.WEATHER)) {
fragment = new WeatherFragmentPhone();
}else if (whichView.equals(ConstantsManager.ALARM)) {
fragment = new AlarmFragmentPhone();
}else if (whichView.equals(ConstantsManager.MAPS)) {
fragment = new MapPhone();
}else if (whichView.equals(ConstantsManager.HELP)) {
fragment = new InfoFragPhone();
}
if (whichView.equals(ConstantsManager.MAPS)) { // to show plus-icon on map top right corner
HomeFragment.getInstance().onGridViewVisibilityChanged(true);
HomeFragmentTab.getInstance().onFragmentTabChange(View.VISIBLE , title, "", View.VISIBLE);
} else if (!whichView.equals(ConstantsManager.GRIDVIEWPAGER)) {
HomeFragment.getInstance().onGridViewVisibilityChanged(true);
HomeFragmentTab.getInstance().onFragmentTabChange(View.VISIBLE , title, mPhoneNo, View.GONE);
}
fragment.setArguments(b);
ft.add(R.id.main_home_frag, fragment);
if (whichView.equals(ConstantsManager.GRIDVIEWPAGER)) {
fragmentManager.popBackStack();
} else {
ft.addToBackStack(fragment.toString());
}
ft.commit();
}
#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 arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTabChanged(String tabId) {
// TODO Auto-generated method stub
}
}
and my HomeFragmentTab.java is
package com.bbgusa.bbgdemo.ui.home.phone;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.bbgusa.bbgdemo.R;
import com.bbgusa.bbgdemo.ui.phone.MainActivity;
import com.bbgusa.bbgdemo.ui.tablet.ConstantsManager;
import com.bbgusa.bbgdemo.ui.tablet.OnFragmentTabChangedListener;
#SuppressLint("NewApi")
public class HomeFragmentTab extends Fragment implements OnFragmentTabChangedListener{
private static final String TAG = HomeFragmentTab.class.getSimpleName();
private static HomeFragmentTab tab;
private MainActivity activityPhone;
public static HomeFragmentTab getInstance() {
return tab;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
activityPhone = (MainActivity) activity;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v;
if (container == null) {
return null;
}
Log.i(TAG, "onCreateView");
v = inflater.inflate(R.layout.hometab_phone, container, false);
tab = this;
activityPhone.onFragmentChangePhone(null, ConstantsManager.GRIDVIEWPAGER, getResources().getString(R.string.app_name), "");
return v;
}
#Override
public void onFragmentTabChange(int i, String title, String mPhoneNo, int mapV) {
}
}
and HomeFragment.java is
package com.bbgusa.bbgdemo.ui.home.phone;
import java.util.Locale;
import org.json.JSONArray;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.bbgusa.bbgdemo.R;
import com.bbgusa.bbgdemo.ui.ImageCacheManager;
import com.bbgusa.bbgdemo.ui.cms.tablet.TestTopics;
import com.bbgusa.bbgdemo.ui.cms.tablet.TopicList;
import com.bbgusa.bbgdemo.ui.phone.MainActivity;
import com.bbgusa.bbgdemo.ui.tablet.onGridViewVisibilityChangedListener;
import com.bbgusa.bbgdemo.utils.common.UCConstants;
import com.bbgusa.bbgdemo.utils.common.UConnectUtils;
import com.viewpagerindicator.IconPageIndicator;
import com.viewpagerindicator.IconPagerAdapter;
import com.viewpagerindicator.PageIndicator;
public class HomeFragment extends Fragment implements onGridViewVisibilityChangedListener{
private static final String TAG = HomeFragment.class.getSimpleName();
private ViewPager mViewPager;
private MainActivity activity;
private PageIndicator mIndicator;
private Animation mRotateAnim;
private Dialog indiacatorDialog;
private LinearLayout homeFragmentLL;
private static HomeFragment homeFragment;
public static final HomeFragment getInstance() {
return homeFragment;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.activity = (MainActivity) activity;
}
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
View v = inflater.inflate(R.layout.home_phone, container, false);
homeFragment = this;
UConnectUtils.setLauncher(true);
mViewPager = (ViewPager) v.findViewById(R.id.viewpager);
mIndicator = (IconPageIndicator) v.findViewById(R.id.indicator);
homeFragmentLL = (LinearLayout) v.findViewById(R.id.homeFragment);
indiacatorDialog = new Dialog(getActivity());
indiacatorDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
indiacatorDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
indiacatorDialog.setContentView(R.layout.indicator_dialog);
indiacatorDialog.setCanceledOnTouchOutside(false);
Window window = indiacatorDialog.getWindow();
window.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
mRotateAnim = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_and_scale);
UConnectUtils.addAnimationFrameCount(mRotateAnim);
indicatorAnim();
// for property id
// if (activity.isInterNetAvailable()) {
Log.i(TAG, "onCreateView========== isInterNetAvailable");
new CmsPropertyAsync(activity).execute(UCConstants.CMS_CONFIG_URL, UCConstants.CMS_CONFIG_KEY);
// }
return v;
}
protected void parseJson(JSONObject rootResponce) {
TestTopics.imageUrls.clear();
TestTopics.titles.clear();
TestTopics.mMainMenuID.clear();
TestTopics.mViewType.clear();
TestTopics.mPhoneNo.clear();
try {
//get the Version
String version = rootResponce.optString("VERSION");
SharedPreferences mPref;
SharedPreferences.Editor edit;
mPref = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
edit = mPref.edit();
edit.putString(getResources().getString(R.string.pref_cms_version_key), version).commit();
JSONArray jsonArray = rootResponce.getJSONArray("MAINMENU");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject childMenuObject = jsonArray.getJSONObject(i);
int mainMenuID = childMenuObject.optInt("mainMenuId");
String title = childMenuObject.optString("title");
String viewType = childMenuObject.optString("viewType");
String imageUrl = childMenuObject.optString("imageUrl");
String phoneNo = childMenuObject.optString("phoneNo");
TestTopics.mMainMenuID.add(mainMenuID);
TestTopics.imageUrls.add(imageUrl);
TestTopics.titles.add(title);
TestTopics.mViewType.add(viewType);
TestTopics.mPhoneNo.add(phoneNo);
}
// Create a TopicList for this demo. Save it as the shared instance
// in
// TopicList
String sampleText = getResources().getString(R.string.sample_topic_text);
TopicList tlist = new TopicList(sampleText);
TopicList.setInstance(tlist);
// Create an adapter object that creates the fragments that we need
// to display the images and titles of all the topics.
MyAdapter mAdapter = new MyAdapter(getActivity().getSupportFragmentManager(), tlist, getResources());
// mViewPager.removeAllViews();
mViewPager.setAdapter(mAdapter);
// mViewPager.setPageTransformer(true, new DepthPageTransformer());
mIndicator.setViewPager(mViewPager);
mIndicator.setCurrentItem(0);
mIndicator.notifyDataSetChanged();
ViewTreeObserver observer = mViewPager.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
mViewPager.bringChildToFront(mViewPager.getChildAt(0));
if(Build.VERSION.SDK_INT >= UCConstants.ICE_CREAM_SANDWICH_MR1){
mViewPager.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}else{
mViewPager.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
/*Fragment f = new GridViewFragment();
FragmentTransaction t = getFragmentManager().beginTransaction();
t.replace(R.id.main_home_frag, f);
t.commit();*/
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Adapter class
*
* This adapter class sets up GridFragment objects to be displayed by a
* ViewPager.
*/
public static class MyAdapter extends FragmentStatePagerAdapter implements IconPagerAdapter {
private TopicList mTopicList;
private int mNumItems = 0;
private int mNumFragments = 0;
/**
* Return a new adapter.
*/
public MyAdapter(FragmentManager fm, TopicList db, Resources res) {
super(fm);
setup(db, res);
}
/**
* Get the number of fragments to be displayed in the ViewPager.
*/
#Override
public int getCount() {
Log.i(TAG, "getCount : mNumFragments = "+mNumFragments);
return mNumFragments;
}
/**
* Return a new GridFragment that is used to display n items at the
* position given.
*
* #param position
* int - the position of the fragement; 0..numFragments-1
*/
#Override
public Fragment getItem(int position) {
// Create a new Fragment and supply the fragment number, image
// position, and image count as arguments.
// (This was how arguments were handled in the original pager
// example.)
Bundle args = new Bundle();
args.putInt("num", position + 1);
args.putInt("firstImage", position * mNumItems);
// The last page might not have the full number of items.
int imageCount = mNumItems;
if (position == (mNumFragments - 1)) {
int numTopics = mTopicList.getNumTopics();
int rem = numTopics % mNumItems;
if (rem > 0)
imageCount = rem;
}
args.putInt("imageCount", imageCount);
args.putSerializable("topicList", TopicList.getInstance());
// Return a new GridFragment object.
Log.i(TAG, "created fragmenat number:==== "+position+" "+1);
GridViewFragmentPhone f = new GridViewFragmentPhone();
f.setArguments(args);
Log.i(TAG, "getItem : imageCount = "+imageCount);
return f;
}
/**
* Set up the adapter using information from a TopicList and resources
* object. When this method completes, all the instance variables of the
* adapter are valid;
*
* #param tlist
* TopicList
* #param res
* Resources
* #return void
*/
void setup(TopicList tlist, Resources res) {
mTopicList = tlist;
if ((tlist == null) || (res == null)) {
mNumItems = 2;//DEFAULT_NUM_ITEMS;
mNumFragments = 2;//DEFAULT_NUM_FRAGMENTS;
} else {
int numTopics = tlist.getNumTopics();
int numRowsGV = res.getInteger(R.integer.num_of_rows_gridview);
int numColsGV = res.getInteger(R.integer.num_of_cols_gridview);
int numTopicsPerPage = numRowsGV * numColsGV;
int numFragments = numTopics / numTopicsPerPage;
if (numTopics % numTopicsPerPage != 0)
numFragments++; // Add one if there is a partial page
mNumFragments = numFragments;
mNumItems = numTopicsPerPage;
}
} // end setup
#Override
public int getIconResId(int index) {
int[] ICON = new int[mNumFragments];
for (int i = 0; i < mNumFragments; i++) {
ICON[i] = R.drawable.slidericon;
}
return ICON[index % ICON.length];
}
} // end class MyAdapter
#Override
public void onGridViewVisibilityChanged(boolean hide) {
if(hide){
homeFragmentLL.setVisibility(View.GONE);
}else {
homeFragmentLL.setVisibility(View.VISIBLE);
}
}
#Override
public void onDetach() {
super.onDetach();
activity = null;
}
#Override
public void onDestroy() {
super.onDestroy();
}
private class CmsPropertyAsync extends AsyncTask<String, Void, String> {
MainActivity context;
CmsPropertyAsync(MainActivity activityTab) {
context = activityTab;
}
#Override
protected String doInBackground(String... params) {
String propertyId = UConnectUtils.getPropertyId(PreferenceManager.getDefaultSharedPreferences(context),getResources().getString(R.string.property_id));
if(propertyId != null && propertyId.length() > 0){
return propertyId;
}
return UConnectUtils.requestPropertyId(params[0], params[1]);
}
#Override
protected void onPostExecute(String propertyId) {
if(propertyId == null){
indiacatorDialog.dismiss();
showPropertyIdTimeoutAlert(getActivity());
return;
}
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
editor.putString(getString(R.string.property_id),propertyId).commit();
String url = null;
String locale = Locale.getDefault().getLanguage();
url = UCConstants.CMS_BASE_URL+"mainMenu?propertyId="+propertyId+"&lang="+locale;
JsonObjectRequest jsObjRequest = new JsonObjectRequest(
Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
parseJson(response);
indiacatorDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (activity != null) {
// activity.getConnection(error);
}
indiacatorDialog.dismiss();
}
});
ImageCacheManager.getInstance().getQueueForMainmenu().add(jsObjRequest);
}
}
private void indicatorAnim() {
if (indiacatorDialog != null) {
ImageView alertIndicator = (ImageView) indiacatorDialog.findViewById(R.id.alert_indicator);
alertIndicator.startAnimation(mRotateAnim);
if (!getActivity().isFinishing()) {
indiacatorDialog.show();
}
}
}
// Show alert for Time out
private void showPropertyIdTimeoutAlert(final Activity context) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setIcon(R.drawable.alert_dialog_icon);
alertDialog.setTitle(context.getString(R.string.timeout_msg));
alertDialog.setMessage(context.getString(R.string.timeout_msg2));
alertDialog.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
indicatorAnim();
// for property id
new CmsPropertyAsync(activity).execute(UCConstants.CMS_CONFIG_URL, UCConstants.CMS_CONFIG_KEY);
}
});
alertDialog.setNegativeButton("Cancel", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
getActivity().finish();
}
});
AlertDialog alert = alertDialog.create();
alert.setCancelable(false);
alert.setCanceledOnTouchOutside(false);
if (context != null && !context.isFinishing()) {
alert.show();
}
}
}
Actually, some data is being saved with onSavedInstaceState(). The data is not being deleted when process has been killed on LowMemory.
I fixed this with
#Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
}
Just do not call super class. Just comment like above
I'm using customized ListView in android, and using search with customized EditText. When I search for a name, I will get the result using getFilter().filter(cs);. But, when I rotate, the ListView shows the full list (without filtering), then after a delay, it shows the filtered list.
When I rotate without filtering, it maintains the listview position.
So I have to maintain the filtered ListView when I rotate the screen.
Please help. Thanks in advance...
import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.LoaderManager;
import android.content.Context;
import android.content.Loader;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
#SuppressLint("HandlerLeak")
public class ContactsListActivity
extends Activity
implements LoaderManager.LoaderCallbacks<ArrayList<ListViewItem>> {
private LetterScrollListView mLSListView;
private ProgressBar mProgressBar;
private EditText mSearchText;
private ProgressBar mSearchProgressBar;
private LinearLayout mViewsLl;
private ContactAdapter mFullContactAdapter = null;
private ArrayList<ListViewItem> mFullContactsArrayList = null;
public boolean isSoftKeyOn = false;
public boolean isPortrait;
private long mLastTimeTextChanged = 0L;
private long mCurrentTime = 0L;
private Filter mFilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts_list);
RelativeLayout windowRl = (RelativeLayout) findViewById(R.id.window_RelativeLayout);
LinearLayout progressBarLl = (LinearLayout) windowRl.findViewById(R.id.progressBar_LinearLayout);
mViewsLl = (LinearLayout) windowRl.findViewById(R.id.views_LinearLayout);
mSearchText = (EditText) mViewsLl.findViewById(R.id.contact_SearchEditText);
mSearchProgressBar = (ProgressBar) mViewsLl.findViewById(R.id.search_ProgressBar);
mLSListView = (LetterScrollListView) mViewsLl.findViewById(R.id.contacts_LetterScrollListView);
mLSListView.setSearchText(mSearchText);
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
isPortrait = true;
} else {
isPortrait = false;
}
final View activityRootView = windowRl;
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int heightDiff = activityRootView.getRootView()
.getHeight() - activityRootView.getHeight();
// if heightDiff > 100 pixels, its probably a keyboard...
if (heightDiff > 100) {
// Toast.makeText(getApplicationContext(), "Key ON",
// Toast.LENGTH_SHORT).show();
isSoftKeyOn = true;
} else {
// Toast.makeText(getApplicationContext(), "Key OFF",
// Toast.LENGTH_SHORT).show();
isSoftKeyOn = false;
mSearchText.clearFocus();
}
}
});
mSearchText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2,
int arg3) {
mCurrentTime = System.currentTimeMillis();
if( (mCurrentTime - mLastTimeTextChanged) <= USER_TYPE_DELAY ) {
mSearchInputHandler.removeMessages(WHAT_SEARCH);
}
// preparing message
Bundle bundle = new Bundle();
bundle.putCharSequence(USER_INPUT_KEY, cs);
Message message = mSearchInputHandler.obtainMessage(WHAT_SEARCH);
message.setData(bundle);
mSearchInputHandler.sendMessageDelayed(message, USER_TYPE_DELAY);
mLastTimeTextChanged = mCurrentTime;
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
// Create a progress bar to display while the list loads
mProgressBar = new ProgressBar(this);
mProgressBar.setIndeterminate(true);
progressBarLl.addView(mProgressBar);
getLoaderManager().initLoader(0, null, this).forceLoad();
}
#SuppressLint("HandlerLeak")
private final Handler mSearchInputHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
CharSequence cs = msg.getData().getCharSequence(USER_INPUT_KEY);
int what = msg.what;
switch(what) {
case WHAT_SEARCH:
// When user changed the Text after a delay
mSearchProgressBar.setVisibility(View.VISIBLE);
mFilter.filter(cs);
break;
}
}
};
public void removeSearchProgressBar() {
mSearchProgressBar.setVisibility(View.INVISIBLE);
}
/**
* Called when a new Loader needs to be created
*/
public Loader<ArrayList<ListViewItem>> onCreateLoader(int id, Bundle args) {
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME
};
boolean showInvisible = false;
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" +
(showInvisible ? "0" : "1") + "'";
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
return new ContactArrayListLoader(this, uri, projection, selection, selectionArgs, sortOrder);
}
/**
* Called when a previously created loader has finished loading
*/
public void onLoadFinished(Loader<ArrayList<ListViewItem>> loader, ArrayList<ListViewItem> data) {
mProgressBar.setVisibility(View.INVISIBLE);
if(mLSListView.getAdapter() == null) {
mFullContactsArrayList = data;
mFullContactAdapter = new ContactAdapter(this, R.layout.contact_tuple, mFullContactsArrayList);
mFilter = mFullContactAdapter.getFilter();
mLSListView.setAdapter(mFullContactAdapter);
}
}
/**
* Called when a previously created loader is reset, making the data unavailable
*/
public void onLoaderReset(Loader<ArrayList<ListViewItem>> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
//////mListView.setAdapter(new ContactAdapter(this, R.layout.contact_tuple, null));
mProgressBar.setVisibility(View.VISIBLE);
}
}
SOLVED
The problem is on the method
public void onLoadFinished(Loader<ArrayList<ListViewItem>> loader, ArrayList<ListViewItem> data) {....}
On rotation/starting the app, the parameter data in this method is always the complete list and not the filtered list. So to get the filtered list on rotation, just create a static member
private static ArrayList<ListViewItem> sCurrentContactsArrayList = null;
and save before screen rotation like this:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if( TextUtils.isEmpty(mSearchText.getText()) ) {
sCurrentContactsArrayList = null;
} else {
sCurrentContactsArrayList = mFullContactAdapter.getCurrentItems();
}
}
also modify onLoadFinished():
public void onLoadFinished(Loader<ArrayList<ListViewItem>> loader, ArrayList<ListViewItem> data) {
mProgressBar.setVisibility(View.INVISIBLE);
if(mLSListView.getAdapter() == null) {
ArrayList<ListViewItem> contactsAL = null;
if(sCurrentContactsArrayList == null) {
contactsAL = data;
} else {
contactsAL = sCurrentContactsArrayList;
}
mFullContactAdapter = new ContactAdapter(this, R.layout.contact_tuple, contactsAL, data);
if(mFilter == null) mFilter = mFullContactAdapter.getFilter();
mLSListView.setAdapter(mFullContactAdapter);
}
mSearchText.setVisibility(View.VISIBLE);
}
I am fetching information from the website in JSON Format and displaying that info into my app using AsynTask. The Problem is that on On First time my Progress dialog shows well and hide after loading contents into app. But When i use Scroll-view to load more then progress dialog appears and hide after loading immediately at the same time progress dialog opens again and not hiding and Scroll-View loads data one more time in the background.I want only one time to load data after each using Scroll-View to load more. Progress Dialog is not hiding and It keeps running my app. I am struck at this point.
Basically i noticed that My Scroll-View indicator collide two times on the bottom due to this scroll-View trigger two times. How can i stop it and restrict this only one time after each scrolling.
And one more thing wanna share that everything is working awesome in Froyo 2.2 and not working in 2.3 to 4.2. Kindly help me on this. Thanks in advance.
Below is my code.
package com.example.lmf;
import java.net.URLEncoder;
import org.json.JSONArray;
import org.json.JSONObject;
import com.example.lmf.ObservableScrollView.ScrollViewListener;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Toast;
public class searchClassified extends Activity implements ScrollViewListener
{
ObservableScrollView scrollView;
ProgressDialog _progressDialog;
int page_no = 1;
String k = "";
final static String URL = "http://www.lmf.com.pk/admin/json.php?YOUR URL OF JSON";
final getInternetData obj = new getInternetData();
public ImageLoader imageLoader = null;
Context context = this;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.get_classified);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
scrollView = (ObservableScrollView) findViewById(R.id.my_scroll);
scrollView.setScrollViewListener(this);
imageLoader = new ImageLoader(this);
String s = getIntent().getExtras().getString("query")!= "" ? getIntent().getExtras().getString("query") : "";
EditText et = (EditText) findViewById(R.id.query);
et.setText(s);
k = "all="+URLEncoder.encode(s);
//showProgress(context);
new getBackgroundData().execute();
}
public void onScrollEnded(ObservableScrollView scrollView, int x, int y,
int oldx, int oldy) {
// TODO Auto-generated method stub
page_no = page_no + 1;
k = k+"&page_no="+page_no;
//showProgress(context);
getBackgroundData d1 = new getBackgroundData();
d1.execute();
if(d1.getStatus()==AsyncTask.Status.FINISHED) {
d1 = null;
_progressDialog.dismiss();
}
}
public void searchAds(View v)
{
EditText query = (EditText) findViewById(R.id.query);
String q = query.getText().toString();
if(q == "" || q == "search")
{
Dialog d = new Dialog(this);
d.setTitle("Enter Valid Search Parameter");
d.show();
}
else
{
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Intent i = new Intent(searchClassified.this,com.example.lmf.searchClassified.class);
i.putExtra("query", ""+q+"");
startActivity(i);
}
}
public void showProgress(Context c)
{
_progressDialog = ProgressDialog.show(
c,
"Please wait",
"Performing task..."
);
}
public void hideProgress()
{
_progressDialog.dismiss();
}
//////////// Async Class
private class getBackgroundData extends AsyncTask<Void, Integer, JSONArray>
{
protected void onPreExecute()
{
_progressDialog = new ProgressDialog(context);
_progressDialog.setMessage("Loading...");
_progressDialog.show();
}
#Override
protected JSONArray doInBackground(Void... params)
{
try
{
JSONArray array = obj.getDATA(k,URL);
return array;
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONArray array)
{
LinearLayout sv = (LinearLayout) findViewById(R.id.data);
try
{
for (int i = 0; i <array.length(); i++) {
JSONObject row = array.getJSONObject(i);
//// TextView Creation start here /////////
TextView tv = (TextView)getLayoutInflater().inflate(R.layout.tvtemplate, null);
tv.setText(row.getString("post_title"));
tv.setTextColor(Color.BLACK);
tv.setTextSize(14);
tv.setPadding(8, 6, 0, 12);
tv.setFocusable(true);
tv.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
//// TextView Creating Ends here /////////
//// Horizontal Line Creating here /////////
View v = new View(searchClassified.this);
LinearLayout.LayoutParams viewLp = new LayoutParams(LayoutParams.MATCH_PARENT, 1);
viewLp.setMargins(0, 4, 0, 4);
v.setLayoutParams(viewLp);
v.setBackgroundColor(Color.LTGRAY);
//// Horizontal Line Creating Ends here /////////
//// Image Creating Starts from here /////////
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.setMargins(3, 0, 15, 8);
lp.width = 70;
lp.height = 80;
ImageView imageView = new ImageView(searchClassified.this);
String[] parts = row.getString("post_img").split("/");
int last_index = parts.length - 1;
String image_name = "thumb_"+parts[last_index];
String str = "";
for(int j=0; j<last_index; j++)
{
str += parts[j]+"/";
}
String path = "http://www.lmf.com.pk/"+str+image_name;
imageLoader.DisplayImage(path, imageView);
//// Image Creating Ends here /////////
// Creating LinearLAyout /////////
LinearLayout l1 = new LinearLayout(searchClassified.this);
l1.setOrientation(LinearLayout.HORIZONTAL);
l1.setHapticFeedbackEnabled(true);
l1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
l1.setId(obj.convertStrtoInt(row.getString("post_id")));
l1.setHapticFeedbackEnabled(true);
l1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(searchClassified.this,com.example.lmf.adsDetail.class);
i.putExtra("id", v.getId());
startActivity(i);
}
});
l1.addView(imageView, lp);
l1.addView(tv);
sv.addView(l1);
sv.addView(v);
}
_progressDialog.hide();
_progressDialog.dismiss();
_progressDialog = null;
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
/////////// Ends Here
public boolean onCreateOptionsMenu(Menu menu)
{
MenuItem item = menu.add ("Quit");
item.setOnMenuItemClickListener (new OnMenuItemClickListener()
{
public boolean onMenuItemClick (MenuItem item)
{
//clearArray();
finish();
return true;
}
});
return true;
}
}
I have Solved this issue and want to share with the future readers. I made a switch and add cases now the new Scroll-View trigger can not run until the previous data will not complete loads.
Here is the final code and hope will help you friends. Thanks
package com.example.lmf;
import java.net.URLEncoder;
import org.json.JSONArray;
import org.json.JSONObject;
import com.example.lmf.ObservableScrollView.ScrollViewListener;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Toast;
public class searchClassified extends Activity implements ScrollViewListener
{
ObservableScrollView scrollView;
ProgressDialog _progressDialog;
int page_no = 1;
String k = "";
final static String URL = "Your URL HERE For Getting JSON";
final getInternetData obj = new getInternetData();
public ImageLoader imageLoader = null;
Context context = this;
int num = 1;
private static final int SPLASH_DURATION = 3000; // 3 seconds
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.get_classified);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
scrollView = (ObservableScrollView) findViewById(R.id.my_scroll);
scrollView.setScrollViewListener(this);
imageLoader = new ImageLoader(this);
String s = getIntent().getExtras().getString("query")!= "" ? getIntent().getExtras().getString("query") : "";
EditText et = (EditText) findViewById(R.id.query);
et.setText(s);
k = "all="+URLEncoder.encode(s);
showProgress();
new getBackgroundData().execute();
}
public void onScrollEnded(ObservableScrollView scrollView, int x, int y, int oldx, int oldy)
{
// TODO Auto-generated method stub
page_no = page_no + 1;
k = k+"&page_no="+page_no;
switch(num)
{
case 1:
showProgress();
new getBackgroundData().execute();
num = 0;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
num = 1;
}
}, SPLASH_DURATION);
break;
case 0:
num = 0;
break;
}
}
public void searchAds(View v)
{
EditText query = (EditText) findViewById(R.id.query);
String q = query.getText().toString();
if(q == "" || q == "search")
{
Dialog d = new Dialog(this);
d.setTitle("Enter Valid Search Parameter");
d.show();
}
else
{
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Intent i = new Intent(searchClassified.this,com.example.lmf.searchClassified.class);
i.putExtra("query", ""+q+"");
startActivity(i);
}
}
public void showProgress()
{
_progressDialog = new ProgressDialog(context);
_progressDialog.setMessage("Loading...");
_progressDialog.show();
}
public void hideProgress()
{
_progressDialog.dismiss();
}
//////////// Async Class
private class getBackgroundData extends AsyncTask<Void, Integer, JSONArray>
{
#Override
protected JSONArray doInBackground(Void... params)
{
try
{
JSONArray array = obj.getDATA(k,URL);
return array;
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONArray array)
{
LinearLayout sv = (LinearLayout) findViewById(R.id.data);
try
{
for (int i = 0; i <array.length(); i++) {
JSONObject row = array.getJSONObject(i);
//// TextView Creation start here /////////
TextView tv = (TextView)getLayoutInflater().inflate(R.layout.tvtemplate, null);
tv.setText(row.getString("post_title"));
tv.setTextColor(Color.BLACK);
tv.setTextSize(14);
tv.setPadding(8, 6, 0, 12);
tv.setWidth(350);
tv.setHeight(100);
tv.setFocusable(true);
LinearLayout.LayoutParams tvPar = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//tvPar.weight = 2;
tv.setLayoutParams(tvPar);
//// TextView Creating Ends here /////////
//// Horizontal Line Creating here /////////
View v = new View(searchClassified.this);
LinearLayout.LayoutParams viewLp = new LayoutParams(LayoutParams.MATCH_PARENT, 1);
viewLp.setMargins(0, 4, 0, 4);
v.setLayoutParams(viewLp);
v.setBackgroundColor(Color.LTGRAY);
//// Horizontal Line Creating Ends here /////////
//// More Detail Icon Ends /////////////////////
ImageView more_info_icon = new ImageView(searchClassified.this);
//setting image resource
more_info_icon.setImageResource(R.drawable.arrow);
//setting image position
LinearLayout.LayoutParams par = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//par.weight = 1;
more_info_icon.setLayoutParams(par);
more_info_icon.getLayoutParams().height = 30;
more_info_icon.getLayoutParams().width = 30;
more_info_icon.setPadding(0, 14, 0, 0);
/// More Detail Icon Ends Here /////////////////////
//// Image Creating Starts from here /////////
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,4);
lp.weight = 1;
lp.setMargins(3, 0, 15, 8);
lp.width = 70;
lp.height = 80;
ImageView imageView = new ImageView(searchClassified.this);
String[] parts = row.getString("post_img").split("/");
int last_index = parts.length - 1;
String image_name = "thumb_"+parts[last_index];
String str = "";
for(int j=0; j<last_index; j++)
{
str += parts[j]+"/";
}
String path = "http://www.lmf.com.pk/"+str+image_name;
imageLoader.DisplayImage(path, imageView);
//// Image Creating Ends here /////////
// Creating LinearLAyout /////////
final LinearLayout l1 = new LinearLayout(searchClassified.this);
l1.setOrientation(LinearLayout.HORIZONTAL);
l1.setHapticFeedbackEnabled(true);
LinearLayout.LayoutParams LParam = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
LParam.weight = 4;
l1.setLayoutParams(LParam);
l1.setId(obj.convertStrtoInt(row.getString("post_id")));
l1.setHapticFeedbackEnabled(true);
l1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
l1.setBackgroundColor(Color.GREEN);
//l1.setBackgroundColor(Color.WHITE);
Intent i = new Intent(searchClassified.this,com.example.lmf.adsDetail.class);
i.putExtra("id", v.getId());
startActivity(i);
}
});
l1.addView(imageView, lp);
l1.addView(tv);
l1.addView(more_info_icon);
sv.addView(l1);
sv.addView(v);
}
hideProgress();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
/////////// Ends Here
public boolean onCreateOptionsMenu(Menu menu)
{
MenuItem item = menu.add ("Quit");
item.setOnMenuItemClickListener (new OnMenuItemClickListener()
{
public boolean onMenuItemClick (MenuItem item)
{
//clearArray();
finish();
return true;
}
});
return true;
}
}