Wednesday, June 13, 2012

Rotation Changes in Android

Ever thought about WoWing your friends ….or simply just doing cheap tricks with your Android or more ridiculous like plotting your daily Starbucks allowance? Here’ s a neat way of doing exactly that – Screen Orientations & Rotations.
Some basics: Just to clear your frame of mind (..and mine) that is …mmmh
Portrait ..yep UpRight …and
Landscape yep lazy laying. Ok..now lets get to it!
An Example:
Plotting a list of numeric values which are contained in a list view and upon device rotation switches to a graphical plot view of the data. How neat is that!
Portrait List View of your data:

Landscape Graphical Chart View of your data:

Download:
AndroidOrientationChanges.zip
Steps involved:
Modify AndroidManifest.xml to allow for orientation changes and prevent keyboard from popping up.
Write layout XML files – display list
Write Java Activity – charts with DroidCharts
NOTE:
Screen orientation changes are per Activity :
android:configChanges=”orientation|keyboardHidden”
File: AndroidManifest.xml

01<?xml version="1.0" encoding="utf-8"?>
02<manifest
03    xmlns:android="http://schemas.android.com/apk/res/android"
04    package="com.examples"
05    android:versionCode="1"
06    android:versionName="1.0">
07    <application
08        android:icon="@drawable/icon"
09        android:label="@string/app_name"
10        android:debuggable="true">
11        <activity
12            android:name=".DemoList"
13            android:label="@string/app_name"
14            android:configChanges="orientation|keyboardHidden"
15            android:screenOrientation="portrait">
16            <intent-filter>
17                <action
18                    android:name="android.intent.action.MAIN" />
19                <category
20                    android:name="android.intent.category.LAUNCHER" />
21            </intent-filter>
22        </activity>
23 
24        <activity
25            android:name=".DemoCharts"
26            android:configChanges="orientation|keyboardHidden"></activity>
27    </application>
28</manifest>
File: data_listview.xml

01<?xml version="1.0" encoding="utf-8"?>
02<LinearLayout
03    xmlns:android="http://schemas.android.com/apk/res/android"
04    android:orientation="vertical"
05    android:layout_width="fill_parent"
06    android:layout_height="fill_parent">
07     
08    <ListView
09        android:id="@+id/android:list"
10        android:layout_width="fill_parent"
11        android:layout_height="fill_parent">
12    </ListView>
13</LinearLayout>
File: DemoList.java

001import java.util.ArrayList;
002import android.app.ListActivity;
003import android.content.Intent;
004import android.content.res.Configuration;
005import android.os.Bundle;
006import android.util.Log;
007import android.view.View;
008import android.widget.AdapterView;
009import android.widget.ArrayAdapter;
010import android.widget.ListView;
011import android.widget.Toast;
012import android.widget.AdapterView.OnItemClickListener;
013 
014public class DemoList extends ListActivity implements OnItemClickListener
015    {
016        private static final String tag = "DemoList";
017        private ListView listview;
018        private ArrayAdapter<String> listAdapter;
019 
020        // Want to pass data values as parameters to next Activity/View/Page
021        private String params;
022 
023        // Our data for plotting
024        private final double[][] data = { { 1, 1.0 }, { 2.0, 4.0 }, { 3.0, 10.0 }, { 4, 2.0 }, { 5.0, 20 }, { 6.0, 4.0 }, { 7.0, 1.0 }, };
025 
026        @Override
027        public void onCreate(Bundle savedInstanceState)
028            {
029                super.onCreate(savedInstanceState);
030 
031                // Set the View Layer
032                setContentView(R.layout.data_listview);
033 
034                // Get the Default declared ListView @android:list
035                listview = getListView();
036 
037                // List for click events to the ListView items
038                listview.setOnItemClickListener(this);
039 
040                // Get the data to
041                ArrayList<String> dataList = getDataStringList(data);
042 
043                // Create an Adapter to for viewing the ListView
044                listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, dataList);
045 
046                // Bind the adapter to the ListView
047                listview.setAdapter(listAdapter);
048 
049                // Set the parameters to pass to the next view/ page
050                setParameters(data);
051            }
052 
053        private String doubleArrayToString(double[][] dataVals)
054            {
055                StringBuilder strBuilder = new StringBuilder();
056                for (int i = 0; i < dataVals.length; i++)
057                    {
058                        String datum = "[" + String.valueOf(dataVals[i][0]) + "," + String.valueOf(dataVals[i][1]) + "]";
059 
060                        if (i < dataVals.length - 1)
061                            {
062                                strBuilder.append(datum + " , ");
063                            }
064                        else
065                            {
066                                strBuilder.append(datum);
067                            }
068                    }
069                return strBuilder.toString();
070            }
071 
072        /**
073         * Sets parameters for the Bundle
074         *
075         * @param dataList
076         */
077        private void setParameters(double[][] dataVals)
078            {
079                params = toJSON(dataVals);
080            }
081 
082        public String getParameters()
083            {
084                return this.params;
085            }
086 
087        /**
088         * Need todo JSONArray
089         *
090         * @param dataVals
091         * @return
092         */
093        private String toJSON(double[][] dataVals)
094            {
095                StringBuilder strBuilder = new StringBuilder();
096 
097                strBuilder.append("[");
098                strBuilder.append(doubleArrayToString(dataVals));
099                strBuilder.append("]");
100                return strBuilder.toString();
101            }
102 
103        /**
104         *
105         * @param dataVals
106         * @return
107         */
108        private ArrayList<String> getDataStringList(double[][] dataVals)
109            {
110                ArrayList<String> list = new ArrayList<String>();
111 
112                // TODO: CONVERT INTO JSON FORMAT
113                for (int i = 0; i < dataVals.length; i++)
114                    {
115                        String datum = "[" + String.valueOf(dataVals[i][0]) + "," + String.valueOf(dataVals[i][1]) + "]";
116                        list.add(datum);
117                    }
118                return list;
119            }
120 
121        @Override
122        public void onConfigurationChanged(Configuration newConfig)
123            {
124                super.onConfigurationChanged(newConfig);
125 
126                // Create an Intent to switch view to the next page view
127                Intent intent = new Intent(this, DemoCharts.class);
128 
129                // Pass parameters along to the next page
130                intent.putExtra("param", getParameters());
131 
132                // Start the activity
133                startActivity(intent);
134 
135                Log.d(tag, "Orientation Change...");
136                Log.d(tag, "Params: " + getParameters());
137            }
138 
139        @Override
140        public void onItemClick(AdapterView<?> parent, View view, int position, long duration)
141            {
142                // Upon clicking item in list pop a toast
143                String msg = "#Item: " + String.valueOf(position) + " - " + listAdapter.getItem(position);
144                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
145            }
146    }
File: DemoCharts.java

001import java.util.ArrayList;
002 
003import net.droidsolutions.droidcharts.core.data.XYDataset;
004import net.droidsolutions.droidcharts.core.data.xy.XYSeries;
005import net.droidsolutions.droidcharts.core.data.xy.XYSeriesCollection;
006import android.app.Activity;
007import android.content.Intent;
008import android.content.res.Configuration;
009import android.os.Bundle;
010import android.util.Log;
011import android.widget.Toast;
012 
013public class DemoCharts extends Activity
014    {
015        private static final String tag = "DemoCharts";
016        private final String chartTitle = "My Daily Starbucks Allowance";
017        private final String xLabel = "Week Day";
018        private final String yLabel = "Allowance";
019 
020        /** Called when the activity is first created. */
021        @Override
022        public void onCreate(Bundle savedInstanceState)
023            {
024                super.onCreate(savedInstanceState);
025 
026                // Access the Extras from the Bundle
027                Bundle params = getIntent().getExtras();
028 
029                // If we get no parameters, we do nothing
030                if (params == null) { return; }
031 
032                // Get the passed parameter values
033                String paramVals = params.getString("param");
034 
035                Log.d(tag, "Data Param:= " + paramVals);
036                Toast.makeText(getApplicationContext(), "Data Param:= " + paramVals, Toast.LENGTH_LONG).show();
037 
038                ArrayList<ArrayList<Double>> dataVals = stringArrayToDouble(paramVals);
039 
040                XYDataset dataset = createDataset("My Daily Starbucks Allowance", dataVals);
041                XYLineChartView graphView = new XYLineChartView(this, chartTitle, xLabel, yLabel, dataset);
042                setContentView(graphView);
043            }
044 
045        private String arrayToString(String[] data)
046            {
047                StringBuilder strBuilder = new StringBuilder();
048                for (int i = 0; i < data.length; i++)
049                    {
050                        strBuilder.append(data[i]);
051                    }
052                return strBuilder.toString();
053            }
054 
055        private String cleanNumericString(String val)
056            {
057                return val.replaceAll("\\[", "").replaceAll("\\]", "").trim();
058            }
059 
060        private ArrayList<ArrayList<Double>> stringArrayToDouble(String paramVals)
061            {
062                ArrayList<ArrayList<Double>> plotVals = new ArrayList<ArrayList<Double>>();
063                if (paramVals.startsWith("[") && paramVals.endsWith("]"))
064                    {
065                        String[] vals = paramVals.substring(1, paramVals.length() - 1).split(" , ");
066                        for (String v : vals)
067                            {
068                                if (v.startsWith("[") && v.endsWith("]"))
069                                    {
070                                        String[] dataVals = v.split(",");
071 
072                                        String xvalStr = cleanNumericString(dataVals[0]);
073                                        String yvalStr = cleanNumericString(dataVals[1]);
074                                        Log.d(paramVals, xvalStr + " - " + yvalStr);
075 
076                                        // Convert to Numeric Values
077                                        Double x = Double.parseDouble(xvalStr);
078                                        Double y = Double.parseDouble(yvalStr);
079 
080                                        // Create (x,y) tuple for data point
081                                        ArrayList<Double> list1 = new ArrayList<Double>();
082                                        list1.add(x);
083                                        list1.add(y);
084 
085                                        // Add to our final list
086                                        plotVals.add(list1);
087                                    }
088                                Log.d(tag, "Values to plot: " + plotVals.toString());
089                            }
090                    }
091                return plotVals;
092            }
093 
094        /**
095         * Creates a sample dataset.
096         *
097         * @return a sample dataset.
098         */
099        private XYDataset createDataset(String title, ArrayList<ArrayList<Double>> dataVals)
100            {
101                final XYSeries series1 = new XYSeries(title);
102                for (ArrayList<Double> tuple : dataVals)
103                    {
104                        double x = tuple.get(0).doubleValue();
105                        double y = tuple.get(1).doubleValue();
106 
107                        series1.add(x, y);
108                    }
109 
110                // Create a collection to hold various data sets
111                final XYSeriesCollection dataset = new XYSeriesCollection();
112                dataset.addSeries(series1);
113                return dataset;
114            }
115 
116        @Override
117        public void onConfigurationChanged(Configuration newConfig)
118            {
119                super.onConfigurationChanged(newConfig);
120                Toast.makeText(this, "Orientation Change", Toast.LENGTH_SHORT);
121 
122                // Lets get back to our DemoList view
123                Intent intent = new Intent(this, DemoList.class);
124                startActivity(intent);
125 
126                // Finish current Activity
127                this.finish();
128            }
129    }

No comments:

Post a Comment