I have an app that needs to capture a customer's signature and then present it in an ImageView. For proof-of-concept, I've written a small app that has a layout with a GestureOverlayView at the top, then a "Save Signature" button, then an ImageView below. When I press the Save Signature button, it should create an image from the GestureOverlayView and display it in the ImageView. Below is the code/layout and then a list of issues:
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.gesture.GestureOverlayView android:id="#+id/GestureView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#FFFFFF"
android:fadeEnabled="false"
android:gestureStrokeType="multiple"
android:gestureStrokeWidth="1.5"
android:gestureColor="#000000"
android:fadeOffset="600000"
android:eventsInterceptionEnabled="false"
android:alwaysDrawnWithCache="true">
</android.gesture.GestureOverlayView>
<Button android:id="#+id/SubmitButton"
android:text="Save Signature"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<ImageView android:id="#+id/ImageView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#FFFFFF">
</ImageView>
</LinearLayout>
Code:
public class TestActivity extends Activity {
ImageView iv;
GestureOverlayView gv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iv = (ImageView)findViewById(R.id.ImageView);
gv = (GestureOverlayView)findViewById(R.id.GestureView);
Button submitButton = (Button)findViewById(R.id.SubmitButton);
submitButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Bitmap b = Bitmap.createBitmap(gv.getDrawingCache());
iv.setImageBitmap(b);
}
});
}
}
I get a Null Pointer exception every time on the createBitmap() method. I believe it is because gv.getDrawingCaches() is returning null. As you can see, drawing cache IS enabled so it should return SOMETHING!
Here's the logcat:
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.graphics.Bitmap.createBitmap(Bitmap.java:358)
at com.pgov.barcode.TestActivity$2.onClick(TestActivity.java:42)
at android.view.View.performClick(View.java:2408)
at android.view.View$PerformClick.run(View.java:8816)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
Any and all help would be greatly appreciated!
Apparently I answered my own question. Even though I used:
android:alwaysDrawnWithCache="true"
I changed the code to:
gv.setDrawingCacheEnabled(true);
Bitmap b = Bitmap.createBitmap(gv.getDrawingCache());
iv.setImageBitmap(b);
gv.setDrawingCacheEnabled(false);
And it works! Not sure why the XML flag doesn't affect it though...
Related
I created a 2x2 grid where the first 3 grids has three(Thingspeak) charts imported from GitHub(https://github.com/MacroYau/ThingSpeakAndroid)and the fourth grid will be implemented later so for the time being I just added a blank chart in it.
I have checked out all similar questions on stackoverflow and read their answers and I have understood the error in the logcat at line 60(chartView = (LineChartView) findViewById(R.id.chart);) means that this id is pointing to null but I don't know how to solve it as chart is present as an id in my activity_main.xml layout.
I have used the following files: activity_main.xml, main.xml, TempHumidity.java and GridViewAdapter.java
Code snippet from TempHumidity.java
public class TempHumidity extends AppCompatActivity {
private ThingSpeakChannel tsChannel, tsChannel1, tsChannel2;
private ThingSpeakLineChart tsChart, tsChart1, tsChart2;
private LineChartView chartView, chartView1, chartView2;
GridView simpleGrid;
int charts[] = {R.id.chart, R.id.chart1, R.id.chart2};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
simpleGrid = (GridView) findViewById(R.id.simpleGridView); // init GridView
// Create an object of CustomAdapter and set Adapter to GirdView
GridViewAdapter customAdapter = new GridViewAdapter(getApplicationContext(), charts);
simpleGrid.setAdapter(customAdapter);
// Connect to ThinkSpeak Channels
tsChannel = new ThingSpeakChannel(377467);
tsChannel1 = new ThingSpeakChannel(357670);
tsChannel2 = new ThingSpeakChannel(377509);
// Set listener for Channel feed update events
tsChannel.setChannelFeedUpdateListener(new ThingSpeakChannel.ChannelFeedUpdateListener() {
#Override
public void onChannelFeedUpdated(long channelId, String channelName, ChannelFeed channelFeed) {
// Show Channel ID and name on the Action Bar
getSupportActionBar().setTitle(channelName);
getSupportActionBar().setSubtitle("Channel " + channelId);
// Notify last update time of the Channel feed through a Toast message
Date lastUpdate = channelFeed.getChannel().getUpdatedAt();
Toast.makeText(TempHumidity.this, lastUpdate.toString(), Toast.LENGTH_LONG).show();
}
});
// Fetch the specific Channel feed
tsChannel.loadChannelFeed();
// Create a Calendar object dated 1 minutes ago
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, -1);
// Configure LineChartView
chartView = (LineChartView) findViewById(R.id.chart); //Logcat error points here
chartView.setZoomEnabled(false);
chartView.setValueSelectionEnabled(true);
GridViewAdapter.java
public class GridViewAdapter extends BaseAdapter {
private Context context;
private final int[] charts;
LayoutInflater inflter;
public GridViewAdapter(Context Appcontext, int[] charts) {
this.context = Appcontext;
this.charts = charts;
inflter = (LayoutInflater.from(Appcontext));
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.activity_main, null); // inflate the layout
LineChartView cv = (LineChartView) view.findViewById(R.id.chart); // get the reference of ImageView
return view;
}
#Override
public int getCount() {
return charts.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}
main.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="match_parent"
android:orientation="vertical">
<!--
-->
<GridView
android:id="#+id/simpleGridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:footerDividersEnabled="false"
android:padding="1dp"
android:numColumns="2" />
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Container LinearLayout -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Row 1 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<lecho.lib.hellocharts.view.LineChartView
android:id="#+id/chart"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<lecho.lib.hellocharts.view.LineChartView
android:id="#+id/chart1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
</LinearLayout>
<!-- Row 2 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<lecho.lib.hellocharts.view.LineChartView
android:id="#+id/chart2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<lecho.lib.hellocharts.view.LineChartView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
</LinearLayout>
</LinearLayout>
Logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.macroyau.thingspeakandroid.demo/com.macroyau.thingspeakandroid.demo.TempHumidity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2299)
at android.app.ActivityThread.access$700(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5283)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.macroyau.thingspeakandroid.demo.TempHumidity.onCreate(TempHumidity.java:60)
at android.app.Activity.performCreate(Activity.java:5283)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2299)
at android.app.ActivityThread.access$700(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5283)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
01-14 17:11:28.007 23142-23146/com.macroyau.thingspeakandroid.demo
D/dalvikvm: GC_CONCURRENT freed 587K, 19% free 8887K/10932K, paused 4ms+22ms, total 114ms
When I run the codes(as it is in GitHub) without adding two similar charts in a GridView:
Currently my activity_main.xml layout looks like this:
As Mike M. in the comments pointed out that the chart id is not present in the main.xml file which is the reason why it pointing to null.
All I had to do is remove the main.xml file and set the layout to activity_main.xml in the onCreate method like this:
setContentView(R.layout.activity_main) (as I have already made a 2x2 layout in it activity_main.xml)
and remove the GridViewAdapter.java.
I have the following scenario : on button click dialog should be open in a circular reveal effect.So I have implemented the code.On button click I am facing error NoClassDefFoundError:android.view.ViewAnimatorUtils. Below is my code
MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button)findViewById(R.id.button2);
linearLayout=(LinearLayout) findViewById(R.id.linearLay);
button.setOnClickListener(new View.OnClickListener() {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
public void onClick(View view) {
AlertDialog.Builder builder=new AlertDialog.Builder(getApplicationContext());
int x=view.getWidth()/2;
int y=view.getHeight()/2;
int finalRadius=Math.max(x,y)/2;
Animator anim= ViewAnimationUtils.createCircularReveal(linearLayout,x,y,0,finalRadius);
anim.start();
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
}
});
}
MainActivity.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/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.dhaval.assignment10a.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="#+id/textView" />
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button2"
android:layout_marginLeft="50sp"
android:layout_marginTop="50sp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/textView"
android:layout_marginTop="16dp"
android:id="#id/linearLay">
</LinearLayout>
</RelativeLayout>
Log
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: android.view.ViewAnimationUtils
at com.example.dhaval.assignment10a.MainActivity$1.onClick(MainActivity.java:34)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
ViewAnimationUtils was added in API level 21, you need to set minsdk to 21
What #Diveno says is correct, but if you don't want to set minsdk to 21 you can add this check before instantiating the object:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//now you can use ViewAnimationUtils
}
Here's the entire logcat stack trace:
08-23 02:19:52.826 20628-20628/com.example.sham_tech.lastchance E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.sham_tech.lastchance, PID: 20628
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sham_tech.lastchance/com.example.sham_tech.lastchance.MainActivity}: android.content.res.Resources$NotFoundException: File res/drawable/abc_ic_ab_back_material.xml from drawable resource ID #0x7f020013
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2389)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2441)
at android.app.ActivityThread.access$900(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5345)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/abc_ic_ab_back_material.xml from drawable resource ID #0x7f020013
at android.content.res.Resources.loadDrawable(Resources.java:2152)
at android.content.res.Resources.getDrawable(Resources.java:710)
at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:354)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:193)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawable Manager.java:181)
at android.support.v7.widget.AppCompatDrawableManager.checkVectorDrawableSetup(AppCompatDrawableManager.java:689)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:186)
at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(TintTypedArray.java: 77)
at android.support.v7.app.AppCompatDelegateImplBase.<init> (AppCompatDelegateImplBase.java:83)
at android.support.v7.app.AppCompatDelegateImplV7.<init>(AppCompatDelegateImplV7.java:146)
at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:28)
at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:41)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:193)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:173)
at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:511)
at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:71)
at
com.example.sham_tech.lastchance.MainActivity.onCreate(MainActivity.java:16)
at android.app.Activity.performCreate(Activity.java:5343)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2343)
I cannot understand what's the problem!.
Here's the activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView android:text="Quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
/>
<TextView
android:id="#+id/quantity_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:layout_marginBottom="16dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="SubmitOrder"
/>
</LinearLayout>
Is there anything wrong in the code?
MainActivity.java
package com.example.sham_tech.lastchance;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
/**
* This app displays an order form to order coffee.
*/
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* This method is called when the order button is clicked.
*/
public void submitOrder(View view) {
display(1);
}
/**
* This method displays the given quantity value on the screen.
*/
private void display(int number) {
TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view);
quantityTextView.setText("" + number);
}
}
I have tried to solve it for more than 4 days and there is no result. Please help me!
The problem is that it's looking for a file named "abc_ic_ab_back_material.xml" in your res/drawable/ directory and it's not finding it. Make sure you have that file in that location.
The code you have pasted here did not have referenced the
abc_ic_ab_back_material
If you have used it in the other code, so find if you have the resource named abc_ic_ab_back_material under res/drawable/, if not found, just get one.
If you did not have used it anywhere, just clean you project and rebuild.
I'm trying to use a Tabhostin a Dialog so that the user can toggle inside the Dialog between to layouts. But I always get a NullPointerException. Any advice? or How to do it right?
Dialog Method:
public void dialog(){
final Dialog d = new Dialog(this);
d.setTitle("Dialog);
d.setContentView(R.layout.dialog);
d.setCanceledOnTouchOutside(false);
TabHost tabHost = (TabHost) d.findViewById(android.R.id.tabhost);
Button b_set = (Button) d.findViewById(R.id.b_choose);
Button b_cancel = (Button) d.findViewById(R.id.b_cancel);
tabHost.setup(); //Here is the problem
TabHost.TabSpec tab1 = tabHost.newTabSpec("Favs");
TabHost.TabSpec tab2 = tabHost.newTabSpec("All");
tab1.setIndicator("NEWTAB");
tab1.setContent(new Intent(this,Tab1Activity.class));
tab2.setIndicator("NEWTAB");
tab2.setContent(new Intent(this,Tab2Activity.class));
tabHost.addTab(tab1);
tabHost.addTab(tab2);
d.show();
}
Dialog.xml:
LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabHost
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tabHost">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"></TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</FrameLayout>
</LinearLayout>
</TabHost>
</LinearLayout>
Logcat:
11-30 14:48:06.661 7157-7157/com.test.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.test.app.Main.dialog (Main.java:269)
at com.test.app.Main$1.onClick(Main.java:139)
at android.view.View.performClick(View.java:4475)
at android.view.View$PerformClick.run(View.java:18786)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
TabHost tabHost = (TabHost) d.findViewById(R.id.tabHost);
id is case sensitive
I am trying to use the tabhost when I add it to my xml it doesn't look right, and I believe there is something that needs to be done in java, I am trying to set up three tabs with three different classes is this possible?
Here is my xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/tab1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Browser History:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#+id/tab2"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Call Log"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/call"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#+id/tab3"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Messages"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/tvSms"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
</LinearLayout>
</LinearLayout>
And I have three different classes, because I am trying to use each tab to open each activity.
Here are the Classes
package com.johnnydicamillo.spybeta;
import android.app.Activity;
import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Browser;
import android.widget.TabHost;
import android.widget.TextView;
public class AndroidSpybetaActivity extends TabActivity {
/** Called when the activity is first created. */
Resources res;
TabHost tabHost;
Intent intent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
res = getResources();
tabHost = getTabHost();
TabHost.TabSpec spec;
intent = new Intent().setClass(this, Messaging.class);
spec = tabHost.newTabSpec("messaging").setIndicator("Messaging")
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, TestingData.class);
spec = tabHost.newTabSpec("Calls").setIndicator("Calls")
.setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
TextView view = (TextView) findViewById(R.id.hello);
Cursor mCur = managedQuery(android.provider.Browser.BOOKMARKS_URI,
null, null, null, null);
mCur.moveToFirst();
int index = mCur.getColumnIndex(Browser.BookmarkColumns.TITLE);
while (mCur.isAfterLast() == false) {
view.append(" WebSite " + mCur.getString(index));
mCur.moveToNext();
}
}
}
Second
package com.johnnydicamillo.spybeta;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class Messaging extends TabActivity{
static TextView messageBox;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
messageBox = (TextView) findViewById(R.id.tvSms);
}
public static void updateMessageBox(String msg) {
messageBox.append(msg);
}
}
and third
package com.johnnydicamillo.spybeta;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.widget.TextView;
public class TestingData extends TabActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView view = (TextView) findViewById(R.id.call);
String[] projection = new String[] {
Calls.NUMBER
};
Cursor mCur = managedQuery(CallLog.Calls.CONTENT_URI, projection,
Calls.DURATION + "<?", new String[] { "60" }, Calls.DURATION
+ " ASC");
mCur.moveToFirst();
while (mCur.isAfterLast() == false) {
for (int i = 0; i < mCur.getColumnCount(); i++) {
view.append(" Number " + mCur.getString(i));
}
mCur.moveToNext();
}
}
}
Here is my logcat:
08-12 15:19:16.368: D/AndroidRuntime(280): Shutting down VM
08-12 15:19:16.368: W/dalvikvm(280): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
08-12 15:19:16.628: E/AndroidRuntime(280): FATAL EXCEPTION: main
08-12 15:19:16.628: E/AndroidRuntime(280): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.johnnydicamillo.spybeta/com.johnnydicamillo.spybeta.AndroidSpybetaActivity}: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.johnnydicamillo.spybeta/com.johnnydicamillo.spybeta.Messaging}; have you declared this activity in your AndroidManifest.xml?
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.os.Handler.dispatchMessage(Handler.java:99)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.os.Looper.loop(Looper.java:123)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.ActivityThread.main(ActivityThread.java:4627)
08-12 15:19:16.628: E/AndroidRuntime(280): at java.lang.reflect.Method.invokeNative(Native Method)
08-12 15:19:16.628: E/AndroidRuntime(280): at java.lang.reflect.Method.invoke(Method.java:521)
08-12 15:19:16.628: E/AndroidRuntime(280): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-12 15:19:16.628: E/AndroidRuntime(280): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-12 15:19:16.628: E/AndroidRuntime(280): at dalvik.system.NativeStart.main(Native Method)
08-12 15:19:16.628: E/AndroidRuntime(280): Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.johnnydicamillo.spybeta/com.johnnydicamillo.spybeta.Messaging}; have you declared this activity in your AndroidManifest.xml?
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1404)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.ActivityThread.resolveActivityInfo(ActivityThread.java:2473)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:277)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:651)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.widget.TabHost.setCurrentTab(TabHost.java:323)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.widget.TabHost.addTab(TabHost.java:213)
08-12 15:19:16.628: E/AndroidRuntime(280): at com.johnnydicamillo.spybeta.AndroidSpybetaActivity.onCreate(AndroidSpybetaActivity.java:31)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-12 15:19:16.628: E/AndroidRuntime(280): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
08-12 15:19:16.628: E/AndroidRuntime(280): ... 11 more
08-12 15:19:21.929: I/Process(280): Sending signal. PID: 280 SIG: 9
Yes, it is possible.
You can specify each activity (Start an intent) for each tabs in the following manner
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
res = getResources();
tabHost = getTabHost();
TabHost.TabSpec spec;
intent = new Intent().setClass(this, CalendarActivity.class);
spec = tabHost.newTabSpec("calendar").setIndicator("Calendar", res.getDrawable(R.drawable.ic_tab_calendar)).setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, ProfileActivity.class);
spec = tabHost.newTabSpec("profile").setIndicator("Profile", res.getDrawable(R.drawable.ic_tab_profile)).setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
}
Each activity will have their own content layout views, therefore no need to worry about that in the main layout.
Your main XML layout will be small and simple as
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" />
</LinearLayout>
</TabHost>
I think this is what you want.
It is not possible to have a tab correspond to an activity. The purpose of tabs is to break up one activity into how ever many views if there is too much info display in one view(not to be confused with activity). Here however is how you set up TabHost:
First start with an xml:
<?xml version="1.0" encoding="UTF-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
-
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
-
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<AnalogClock
android:id="#+id/tab1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<Button
android:id="#+id/tab2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="A semi-random button" />
</FrameLayout>
</LinearLayout>
</TabHost>
Sorry that's hard to read but if you copy it into eclipse you should be fine. And then the Java:
import android.app.Activity;
import android.os.Bundle;
import android.widget.TabHost;
public class TabDemo extends Activity {
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
TabHost tabs=(TabHost)findViewById(R.id.tabhost); //Id of tab host
tabs.setup();
TabHost.TabSpec spec=tabs.newTabSpec("tag1");//make a new tab
spec.setContent(R.id.tab1); //What is in the tab (not an activity but rather a view)
spec.setIndicator("Clock"); //Name of tab
tabs.addTab(spec); //Add it
spec=tabs.newTabSpec("tag2"); //Same thing here
spec.setContent(R.id.tab2);
spec.setIndicator("Button");
tabs.addTab(spec);
}
}
This is relatively simple an I am sure there is support in the android development website and of course just searching on Google. This code was copied out of Beginning Android 4 by Grant Allen and the book explains this topic in much greater detail. Good luck!