I am a new developer of Android App and learning all tips from Getting Started. I'm now on the second stage phase 2 "Adding Action Button" and stuck with adding the actions to the action bar. Here is my current situation.
MyfirstApp Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myfirstapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme.Holo.Light" >
<activity
android:name="com.example.myfirstapp.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- A child of the main activity -->
<activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="#string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
</application>
</manifest>
2.main(menu).xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<!-- Search, should appear as action button -->
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
yourapp:showAsAction="ifRoom" />
<!-- Settings, should always be in the overflow -->
<item android:id="#+id/action_settings"
android:title="#string/action_settings"
android:showAsAction="never" />
</menu>
3.MainActivity.java
package com.example.myfirstapp;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
#SuppressLint("ValidFragment")
public class MainActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_displaymessage);
getActionBar().setDisplayHomeAsUpEnabled(true);
// If your minSdkVersion is 11 or higher, instead use:
// getActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
openSearch();
return true;
case R.id.action_settings:
openSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void openSettings() {
}
private void openSearch() {
}
/**
* A placeholder fragment containing a simple view.
*/
public class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
I see two errors from MainActivity.java
1.
inflater.inflate(R.menu.main_activity_actions, menu);
The method inflate(int, Menu) in the type MenuInflater is not applicable for the arguments (Object, Menu)
2.
case R.id.action_search:
case expressions must be constant expressions
I tried to figure out those 2 errors for couple days but I couldn't. Please help.
Related
I have created a simple app by adding action bar to it. And android studio didn't show any issue in the code, but my app keeps crashing when I run it.
I have two activities, in MainActivity I have one button and when you click it it supposed to take you to SecondActivity. And on SecondActivity there should be back arrow in action bar to get back to MainActivity.
Btw I'm using API 16. My activity extends Activity.
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.actionbar3.MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="96dp"
android:text="Next Activity"
android:onClick="onClickButton"/>
</RelativeLayout>
MainActivity:
package com.actionbar3;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.action, menu);
return onCreateOptionsMenu(menu);
}
public void onClickButton(View view){
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
}
}
res/menu/action.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/main_action"
android:title="#string/settings"
android:showAsAction="ifRoom"
android:icon="#drawable/settings"
/>
<item
android:id="#+id/info_action"
android:title="Info"/>
</menu>
ActivitySecond:
package com.actionbar3;
import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
public class SecondActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle("Second Activity");
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.actionbar3">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity" android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
</application>
</manifest>
You are creating a recursion by calling return onCreateOptionsMenu(menu);
so it should be simply return true;
#Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.action, menu);
return true;
// return onCreateOptionsMenu(menu);
// call to itself , mean infinite recursion
}
The onCreateOptionMenu method recurses infinitely, so change it as below
#Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.action, menu);
return true;
}
Extend your activity with AppCompatActivity and use get getSupportActionBar() for backward compatibility
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
public class SecondActivity extends AppCompatActivity {
and create actionbar using getSupportActionBar
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle("Second Activity");
I' have a problem with the app toolbar UP button which never passes the R.id.home on the onOptionsItemSelected method when pressed in a child activity.
The main activity
package com.foocorp.firstapp;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class InstrumentListActivity extends AppCompatActivity
implements IUdpNotificationListener
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_my, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
if (id == R.id.home) {
Toast.makeText(getApplicationContext(), "Clicked Menu back from Main", Toast.LENGTH_SHORT).show();
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
Toast.makeText(getApplicationContext(), "Clicked Hard back from Main", Toast.LENGTH_SHORT).show();
finish();
}
}
The child activity where I set the setDisplayHomeAsUpEnabled(true);
package com.foocorp.firstapp;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class InstrumentViewDetailsActivity extends AppCompatActivity implements IUdpNotificationListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_instrument_view_details);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent intent = getIntent();
//whatever here
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_instrument_view_details, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
//=> never get called because passed ID is never R.id.home
if (id == R.id.home) {
Toast.makeText(getApplicationContext(), "Clicked Menu back from Details", Toast.LENGTH_SHORT).show();
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
Toast.makeText(getApplicationContext(), "Clicked Hard back from Details", Toast.LENGTH_SHORT).show(); // this works fine
finish();
}
}
The manifest file where the parent child relation is defined
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.foocorp.firstapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_tap_and_play_white_24dp"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name="com.foocorp.firstapp.InstrumentListActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".InstrumentViewDetailsActivity"
android:label="#string/instrum_details"
android:parentActivityName="com.foocorp.firstapp.InstrumentListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.foocorp.firstapp.InstrumentListActivity" />
</activity>
</application>
</manifest>
The menu layout file of the child activity (by the way, is it normal that the UP button is not defined here although it appears when the application is running ?)
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.foocorp.firstapp.InstrumentViewDetailsActivity">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
While searching the internet for this solution, I have found the tips about the parent/child relation in the manifest file and the getSupportActionBar().setHomeButtonEnabled(true); but despite theses hints, I can't get this UP toolbar button to work properly : it DOES return to the parent activity BUT not in the proper way like when I press the back button wich calls the onBackPressed() method and which works fine.
Any clue about what I'm missing here ?
Change id of back button from
R.id.home to android.R.id.home in your onOptionsItemSelected() Method.
you can also use NavUtils.navigateUpFromSameTask(this); instead of finish(); as you have mentioned parentActivityName in AndroidManifest.xml.
I was trying to modify an default empty activity and form a default activity with action bar. There are two activities I made, which are both empty without actionbar. What I try to achieve is to click on the first activity(without actionbar) and navigate to the second activity(with actionbar). What I have done are:
1. add a menu
2. modify the second activity by changing the activity to AppCompatActivity
3. add a support library which is v7-appcompat (which was added as a referenced library. I am not sure whether it should be referenced lib or other format.)
The Manifest file part is shown below:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tracker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:label="#string/second" >
</activity>
</application>
</manifest>
The first activity is:
package com.example.tracker;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get the button
Button button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent= new Intent(MainActivity.this,SecondActivity.class);
intent.setAction(Intent.ACTION_VIEW);
startActivity(intent);
}
});
}
}
The second activity is:
package com.example.tracker;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class SecondActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
}
The menu in res is:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.tracker.MainActivity"
>
<item
android:id="#+id/myitem"
android:orderInCategory="2"
android:title="myitem"
app:showAsAction="never"/>
<item
android:id="#+id/action_settings"
android:orderInCategory="1"
android:title="action_settings"
app:showAsAction="never"/>
</menu>
The only observable problem is that the menu has an error which is written in the title of this problem. Currently, the first activity can run properly, however, when I click the button, the application stops.
By removing app:showAsAction="never" does not solve the problem.
Even after defining com.facebook.LoginActivity in my AndroidManifest.xml file the logcat gives the same error and asks to define com.facebook.LoginActivity as activity. I have followed this https://developers.facebook.com/docs/android/login-with-facebook/v2.2#step2 tutorial.
Here is my androidmanifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.log"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.log.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
<activity
android:name="com.facebook.loginActivity"
android:label="#string/app_name" >
</activity>
</application>
</manifest>
MainActivity.java
package com.example.log;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
public class MainActivity extends FragmentActivity {
private MainFragment mainFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.fragment_main);
if (savedInstanceState == null) {
// Add the fragment on initial activity setup
mainFragment = new MainFragment();
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, mainFragment)
.commit();
} else {
// Or set the fragment from restored state info
mainFragment = (MainFragment) getSupportFragmentManager()
.findFragmentById(android.R.id.content);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class MainFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
return view;
}
}
}
fragment_main.xml file
<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:orientation="vertical">
<com.facebook.widget.LoginButton
android:id="#+id/authButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
/>
</LinearLayout>
The facebook login activity is com.facebook.LoginActivity with a capital 'L'. You're using a lower case l.
I am developing an application where I am using a webview. I'm just a beginner in Android and I started to deal with webViews When i tried it in my emulator it doesn't show up. Would really appreciate your help. I am currently using eclipse juno 32 bit windows . I am currently stuck here . This is
MainActivity.java
package bulku.lucky;
import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebView;
#SuppressLint("SetJavaScriptEnabled") public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// applications are run through the emulator
//to access "localhost" from the emulator
String url = "http://e-promotion.al/";
WebView view = (WebView) this.findViewById(R.id.webView1);
view.getSettings().setJavaScriptEnabled(true);
view.loadUrl(url);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
activity_main.xml
<WebView
android:id="#+id/webView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
AndroidManifest.xml
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" tools:ignore="OldTargetApi"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Try adding this to your onCreate (you MUST add a new method and call him in your activity, onCreate method must be as clean as you can, it's just a tip.)
String url = "http://e-promotion.al/";
WebView view = (WebView) this.findViewById(R.id.webView1);
view.getSettings().setJavaScriptEnabled(true);
WebSettings settings = view.getSettings();
settings.getJavaScriptEnabled();
settings.getBuiltInZoomControls();
settings.setBuiltInZoomControls(true); // I use that to show a map in my app, you can delete this line if you want.
view.setWebViewClient(new WebViewClient());
view.loadUrl(url);