Hey guys,
I'm still learning to make android apps and now I'm writing small apps...Today I wrote a small app to test the scrolable tabs+ swipe created with blank activity.I need to show show contents of a PreferenceScreen xml.So I created a xml and added a new class:
Code:
public class About extends PreferenceActivity{
[user=1299008]@supp[/user]ressWarnings("deprecation")
[user=439709]@override[/user]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.info);
addPreferencesFromResource(R.layout.info);
}
}
And then found that the below code is responsible for the screens and so done this:
Code:
[user=439709]@override[/user]
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.example.testy","com.example.testy.About"));
startActivity(intent);
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
Now the thing is that,I need the app to show the contents of xml directly on section1 instead of opening an activity above.Also noted that,when I go to section2,The activity is opened once and when back to section1,twice.
I need to show completely different contents on section1 and section2 also that the contents should be directly on sections instead of opening a new activity over the main one.Sorry for confusing you.All the xml I use are in preferences.Thank you
Regards,
Vijai
vijai2011 said:
Hey guys,
I'm still learning to make android apps and now I'm writing small apps...Today I wrote a small app to test the scrolable tabs+ swipe created with blank activity.I need to show show contents of a PreferenceScreen xml.So I created a xml and added a new class:
Code:
public class About extends PreferenceActivity{
[user=1299008]@supp[/user]ressWarnings("deprecation")
[user=439709]@override[/user]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.info);
addPreferencesFromResource(R.layout.info);
}
}
And then found that the below code is responsible for the screens and so done this:
Code:
[user=439709]@override[/user]
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.example.testy","com.example.testy.About"));
startActivity(intent);
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
Now the thing is that,I need the app to show the contents of xml directly on section1 instead of opening an activity above.Also noted that,when I go to section2,The activity is opened once and when back to section1,twice.
I need to show completely different contents on section1 and section2 also that the contents should be directly on sections instead of opening a new activity over the main one.Sorry for confusing you.All the xml I use are in preferences.Thank you
Regards,
Vijai
Click to expand...
Click to collapse
Change your activity into a FragmentActivity. Then you will be able to add a PreferenceFragment. However, you will need to show the content of your screen in a Fragment instead of the "normal" way of doing it in the onCreate method. Add a Fragment there and if you want to show the preferences, add a new one on the top. It will not open a new Activity but just a new Fragment in the Activity.
nikwen said:
Change your activity into a FragmentActivity. Then you will be able to add a PreferenceFragment. However, you will need to show the content of your screen in a Fragment instead of the "normal" way of doing it in the onCreate method. Add a Fragment there and if you want to show the preferences, add a new one on the top. It will not open a new Activity but just a new Fragment in the Activity.
Click to expand...
Click to collapse
Wait...I dont understand this:
However, you will need to show the content of your screen in a Fragment instead of the "normal" way of doing it in the onCreate method. Add a Fragment there and if you want to show the preferences, add a new one on the top. It will not open a new Activity but just a new Fragment in the Activity.
Click to expand...
Click to collapse
.However I changed my activity to fragment activity from the link you gave
vijai2011 said:
Wait...I dont understand this:.However I changed my activity to fragment activity from the link you gave
Click to expand...
Click to collapse
Yes, change it to a FragmentActivity. It will act like the container of your Fragments. Then you will set the content by adding new Fragments on the top of each other.
Check this: http://developer.android.com/guide/components/fragments.html
Here´s a full example showing how to implement Tabbed Preferences Screen (with no swipe for now). I hope it helps you!!
Entire ICS source code attached!
Screenshots:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Related
I have the Android SDK and Eclipse downloaded and I can get it work properly. However, there doesn't seem to be any commands anywhere, like, am I supposed to know all of the JAVA commands by memory to use this tool???
I only want a very simple app that does this:
- When screen is off, turn WIFI off
- When screen is on, Turn WIFI on
That's it. I don't need any fancy menu or anything, it can run in the background for what I care, it's just that Stamina mode doesn't work with these roms and bootloaders and whatever, so I need this app to save me some power.
I reckon it'd be pretty easy for anyone who knows java, so maybe I could get someone to post a code for me?
Thanks in advance
You don't need to know everything by memory but you do need to know the basics.
For example, you need to know the difference between an Activity and a Service and determine which one you would want to use.
For your app, you would need a Service and a BroadcastReceiver.
Your BroadcastReceiver would capture the intents of the screen turning on and off:
http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
You would then call your service from your broadcastreceiver to do the work of turning off your wifi:
http://stackoverflow.com/questions/8863509/how-to-programmatically-turn-off-wifi-on-android-device
Be sure to add the proper permissions in your manifest file that allows you to read and change wifi state.
Ok, so now I know how the code should be, but there's just one more thing.
How in the world can anyone program a user interface with text only??? This program is certainly not easy to use, I don't even know where to put the code with all of those different folders.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Do I even need all of those commands/folders? I tried deleting all that stuff and putting in the code but I got lots of errors obviously.
So if you would please tell me:
- Where to put the code
- How to make an interface like this one with radio buttons or something, a switch might be easier
I don't want anything fancy, just a super basic app
I suppose the code would look like this:
Code:
package selecm.wwf; //your package name
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
WifiManager wm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
public class ScreenReceiver extends BroadcastReceiver {
// THANKS JASON
public static boolean wasScreenOn = true;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
wm.setWifiEnabled(false)
wasScreenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
wm.setWifiEnabled(true)
wasScreenOn = true;
}
}
}
And then make these in the manifest.xml file:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
Am I right?
Your user interface is located in the "res/layout" folder. It is most likely called activity_main.xml.
Also, I would recommend keeping your BroadcastReceiver separate from your activity. It makes things cleaner to debug and easier to build on.
After doing some playing and spending more time on this then I planned, using a service does not work reliable with the broadcast receiver. I am not sure how logical google was with the thought process of requiring some intents that can only be registered in code. With that limitation, your activity would need to be running to receive the intent from the screen being turned off or on.
I make a android application with a button where in there a total of 4 texts and I want to align the first 2. One at the most left side of the bottom text and the other and the right side of the bottom text.
So from this:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Code:
setText(item.title + " " + item.roomId + "\n" + item.teacher + " " + item.classes);
To this:
This is my class where I extend Button:
Code:
/**
* Custom view that represents a {@link ScheduleItem} instance, including its
* title and time span that it occupies. Usually organized automatically by
* {@link ScheduleItemsLayout} to match up against a {@link TimeRulerView}
* instance.
*/
public class ScheduleItemView extends Button {
private ScheduleItem mItem;
public ScheduleItemView(Context context, ScheduleItem item) {
super(context);
mItem = item;
setSingleLine(false);
setText(item.title + " " + item.roomId + "\n" + item.teacher + " "
+ item.classes);
// TODO: turn into color state list with layers?
int textColor = Color.WHITE;
int accentColor = item.accentColor;
LayerDrawable buttonDrawable = (LayerDrawable) context.getResources()
.getDrawable(R.drawable.btn_block);
buttonDrawable.getDrawable(0).setColorFilter(accentColor,
PorterDuff.Mode.SRC_ATOP);
buttonDrawable.getDrawable(1).setAlpha(item.containsStarred ? 255 : 0);
setTextColor(textColor);
setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources()
.getDimensionPixelSize(R.dimen.text_size_small));
setGravity(Gravity.CENTER | Gravity.BOTTOM);
setBackgroundDrawable(buttonDrawable);
}
public ScheduleItem getScheduleItem() {
return mItem;
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(),
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
getMeasuredHeight(), MeasureSpec.EXACTLY));
// layout(getLeft(), getTop(), getRight(), getBottom());
setGravity(Gravity.CENTER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getRight() - getLeft(), getBottom() - getTop());
}
}
What I've tried is instead of extending Button, extending RelativeLayout:
Code:
/**
* Custom view that represents a {@link ScheduleItem} instance, including its
* title and time span that it occupies. Usually organized automatically by
* {@link ScheduleItemsLayout} to match up against a {@link TimeRulerView}
* instance.
*/
public class ScheduleItemView extends RelativeLayout {
private ScheduleItem mItem;
public ScheduleItemView(Context context, ScheduleItem item) {
super(context);
mItem = item;
// TODO: turn into color state list with layers?
int textColor = Color.WHITE;
int accentColor = item.accentColor;
LayerDrawable buttonDrawable = (LayerDrawable) context.getResources()
.getDrawable(R.drawable.btn_block);
buttonDrawable.getDrawable(0).setColorFilter(accentColor,
PorterDuff.Mode.SRC_ATOP);
buttonDrawable.getDrawable(1).setAlpha(item.containsStarred ? 255 : 0);
// Three TextViews to hold the `title`, `roomId`
// and `teacher&room` independently
TextView tvTitle = new TextView(context);
TextView tvRoomId = new TextView(context);
TextView tvTeacherAndClasses = new TextView(context);
// Example ids
tvTitle.setId(100);
tvRoomId.setId(101);
tvTeacherAndClasses.setId(102);
tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources()
.getDimensionPixelSize(R.dimen.text_size_small));
tvRoomId.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources()
.getDimensionPixelSize(R.dimen.text_size_small));
tvTeacherAndClasses.setTextSize(TypedValue.COMPLEX_UNIT_PX,
getResources().getDimensionPixelSize(R.dimen.text_size_small));
tvTitle.setPadding(30, 20, 30, 0);
tvRoomId.setPadding(30, 20, 30, 0);
tvTeacherAndClasses.setPadding(30, 5, 30, 20);
tvTitle.setTextColor(textColor);
tvRoomId.setTextColor(textColor);
tvTeacherAndClasses.setTextColor(textColor);
// Set text
tvTitle.setText(item.title);
tvRoomId.setText(item.roomId);
tvTeacherAndClasses.setText(item.teacher + " " + item.classes);
// LayoutParms
RelativeLayout.LayoutParams paramsTitle = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
paramsTitle.addRule(RelativeLayout.ALIGN_LEFT,
tvTeacherAndClasses.getId());
RelativeLayout.LayoutParams paramsRoomId = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
paramsRoomId.addRule(RelativeLayout.ALIGN_RIGHT,
tvTeacherAndClasses.getId());
RelativeLayout.LayoutParams paramsTeacherAndClasses = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
paramsTeacherAndClasses.addRule(RelativeLayout.CENTER_HORIZONTAL);
paramsTeacherAndClasses.addRule(RelativeLayout.BELOW, tvTitle.getId());
// Add Views to this RelativeLayout
addView(tvTitle, paramsTitle);
addView(tvRoomId, paramsRoomId);
addView(tvTeacherAndClasses, paramsTeacherAndClasses);
// setGravity(Gravity.CENTER | Gravity.BOTTOM);
// Set the background as LayerDrawable
setBackgroundDrawable(buttonDrawable);
}
public ScheduleItem getScheduleItem() {
return mItem;
}
But then only the LayerDrawable is displaying, the text is not displaying. What I've done wrong? I hope that someone can help me with this, the guys on StackOverflow have point me in a good direction with the above code but it's still not working.
The source of the project can be downloaded here (which you can import in Eclipse):
http://we.tl/5PnmaZKXvL
RelativeLayout should be a good idea!
Have you debuged the app? What is the text of the TextViews? The text-size? Why do you set the ids for the TextViews?
Regards
EmptinessFiller said:
RelativeLayout should be a good idea!
Have you debuged the app? What is the text of the TextViews? The text-size? Why do you set the ids for the TextViews?
Regards
Click to expand...
Click to collapse
I've debugged the app, this is what I've tried:
Log the id's of tvTitle, tvRoomId, and tvTeacherAndClasses with getId() to see if the id's is set. (The id's are set in order to get the addRule working)
I've tried to comment these lines:
tvTitle.setId(100);
tvRoomId.setId(101);
tvTeacherAndClasses.setId(102);
And the following as well:
paramsTitle.addRule(RelativeLayout.ALIGN_LEFT, tvTeacherAndClasses.getId());
paramsRoomId.addRule(RelativeLayout.ALIGN_RIGHT, tvTeacherAndClasses.getId());
paramsTeacherAndClasses.addRule(RelativeLayout.BELOW, tvTitle.getId());
If the ids were the problem, the text should show, but the three textviews would overlap now. But I still see no text.
I've tried to give the TextView a color with tvTitle.setBackgroundColor(Color.GREEN); but I still see no text neither a color.
I've tried to comment out setBackgroundDrawable(buttonDrawable); to see if the text's show up. But then I see no text and no button.
I've also tried to use bringToFront() but neither the text is not showing
As last I've tried to use a concrete value for the TextSize with tvTitle.setTextSize(25) but the text is unfortunately not showing.
What could be the problems:
I use Android-ViewPagerIndicator and ViewPager this could be a problem. (Maybe with restoring the view state or multiple id's).
I've only switched a Button to RelativeLayout, I really don't see why problems being introduced in that transition. Does someone know what could be the problem?
Anyone? I've updated the post with a new download link.
You could call getPaint on the button instance and with measuretext you could get the size of the spaces to calculate the count of spaces for the specific size of the button
Just an idea, no idea how it will work in practice
Tapatalked...
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
I am a person who needs many many multiple alarms to wake up early in the morning.
Every clock/alarm applications I tried has no feature that turning on or off all alarms at once.
So I decided to customize google's official android clock app.
Let's get it started.
### Needed #####
google's clock app source (I use Lollipop's source for my device)
buttons icon image
### Steps #####
1) download source from googlesource.com repository
android system clock application's package name is "DeskClock".
You can clone the source like below
Code:
git clone -b lollipop-release https://android.googlesource.com/platform/packages/apps/DeskClock
2. import it & remove errors
When you import the project to your IDE, you will get thousand of import errors.
Check below
SDK Version
- Make sure that you have lollipop sdk and check "Build Target" in "Project Properties"
AndroidManifest
- Specify min/targetSdkVersion, if it is not in AndroidManifest.xml
- There is "DEVICE_POWER" permission because it is android system app but we can't build system application so just remove it. (In my usage, it seems to be no problem)
Library
- Put android support-library jar file and add it to project build path.
3. Add button icons
- add ic_all_on.png, ic_all_off.png as drawable
4. Edit the sources
There is "DeskClockFragmet" class which is parent of alam/timer/stopwatch/clock's Fragment class.
It uses common layout "desk_clock.xml". It has three buttons (Fab, sub buttons) in the bottom of the screen and Alarm Fragment does not use and just hide sub buttons.
Which means we can easily add buttons to that place.
setLeftRightButtonAppearance() in AlarmClockFragment.java
Code:
@Override
public void setLeftRightButtonAppearance() {
final DeskClock activity = (DeskClock) getActivity();
if (mLeftButton == null || mRightButton == null ||
activity.getSelectedTab() != DeskClock.ALARM_TAB_INDEX) {
return;
}
[COLOR="SeaGreen"] // mLeftButton.setVisibility(View.INVISIBLE);
//mRightButton.setVisibility(View.INVISIBLE);
mLeftButton.setEnabled(true);
mRightButton.setEnabled(true);
mLeftButton.setVisibility(View.VISIBLE);
mRightButton.setVisibility(View.VISIBLE);
mLeftButton.setImageResource(R.drawable.ic_all_off);
mRightButton.setImageResource(R.drawable.ic_all_on);[/COLOR]
}
set mLeft/RightButton enabled and change visibilty to VISIBLE, set button image as drawable we added.
Override onLeftButtonClick/onRightButtonClick() from parent (DeskClockFragment.class) and call switchAlarms() what we will implement.
Code:
@Override
public void onLeftButtonClick(View view) {
super.onLeftButtonClick(view);
mAdapter.switchAlarms(false);
Toast.makeText(getActivity(), "Every Alarms Disabled!!", Toast.LENGTH_SHORT).show();
}
@Override
public void onRightButtonClick(View view) {
super.onRightButtonClick(view);
mAdapter.switchAlarms(true);
Toast.makeText(getActivity(), "Every Alarms Enabled!!", Toast.LENGTH_SHORT).show();
}
+ I just hide menu button in bottom-right just in alarm tab because right and menu button are overlayed.
onCreateView() in AlarmClockFragment.java
Code:
if (menuButton != null) {
// if (isLandscape) {
// menuButton.setVisibility(View.GONE);
// } else {
// menuButton.setVisibility(View.VISIBLE);
// setupFakeOverflowMenuButton(menuButton);
// }
//remove menu button
menuButton.setVisibility(View.GONE);
}
There is AlarmItemAdapter sub class in AlarmClockFragment.java which extends CursorAdapter.
We have to implement something that change actual alarm data in inner database and change views depend on each alarm's on/off value.
I just added a method "swichAlarms" into this sub class to do that.
boolean enabled value is passed as parameter (on : true / off : false)
Get every alarm's view and change the view when the alarm on/off status has to be changed
Also there's a way to get alarms llist in Alarm.java that is getAlarms() method.
I use it to get alarms list a alarm's enabled value is different.
And change alarms enabled value with asyncUpdateAlarm() method in AlarmClockFragment.java
That's all!
easy?
Code:
// added by donghe
/**
* A convenience method to enable or disable every alarm.
* Get child view (visible view) in alarm list and changing ItemAlpha whether if its enabled value is different
* Get alarm(s) linked list from Alarms Class only if the alarm has to be updated.
* Do asynchronous updating.
* @param enabled true for turning on, false for turning off
*/
private void switchAlarms(boolean enabled) {
int totalLength = mList.getCount();
for (int i = 0; i < totalLength; i++) {
View v = mList.getChildAt(i);
if (v != null) {
ItemHolder h = (ItemHolder)(v.getTag());
if (h != null && h.alarm.enabled != enabled) {
setDigitalTimeAlpha(h, enabled);
}
}
}
String selection = null;
if(enabled){
selection = "ENABLED = 0";
}
else{
selection = "ENABLED = 1";
}
ContentResolver cr = getActivity().getApplicationContext().getContentResolver();
List<Alarm> alarmList = Alarm.getAlarms(cr, selection, null);
for(Alarm alarm: alarmList){
alarm.enabled = enabled;
asyncUpdateAlarm(alarm, false);
}
}
Now I feel comfortable to sleep lately in the evening and wake up early in the morning
Hope this thread is helpful to someone like me.
I attached project archive and apk.
Enjoy it!
Thanks men!
Hello,
I create that thread to present you a tutorial learning you to create the game "Spin The Bottle" for Android. It is also a good way to discover how to use Android Animations API.
What is better that creating some funny games to learn the basics of Android development ? Today, you’re going to discover more on the Android Animation API by creating the game “Spin The Bottle”.
Note that you can discover this tutorial in video on Youtube too :
Spin the bottle is a party game in which several players sit/stand/kneel in a circle. A bottle is placed on the floor in the center of the circle. A player spins the bottle, and must kiss the person to whom the bottle points when it stops spinning.
With our application, it is not necessary any more to have a real bottle, you will just need a smartphone. And it’s great because everyone has always a smartphone on him nowadays.
First step is to find two specific images : one for the floor which will be defined as background of the game and an other for the bottle which will be rotated during the game.
We have chosen to use these both images :
Floor image for the background
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Bottle image
Now, we need to define the layout of our game “Spin The Bottle”. We have a Relative Layout with the floor image as background and we add a bottle in the center of this layout :
Code:
<?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/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background">
<ImageView
android:id="@+id/bottle"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/beer_bottle"
android:layout_centerInParent="true" />
</RelativeLayout>
The next step is to write the Java code of the Main Activity. First, we get references for the views. Then, we install a click listener on the main layout of the Main Activity. Thus, the user will just have to touch the screen to spin the bottle and to start the game.
The core of the game is in the spinTheBottle() method. We are going to define a RotateAnimation from start angle to end angle centered on the center of the bottle. The end angle will be defined randomly to simulate really the game “Spin The Bottle”. We should store the last end angle value to restart the bottle in the same position for the next turn of the game.
The Code of the Main Activity will have the following form :
Code:
package com.ssaurel.spinthebottle;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.Toast;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
public static final Random RANDOM = new Random();
private View main;
private ImageView bottle;
private int lastAngle = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
main = findViewById(R.id.root);
bottle = (ImageView) findViewById(R.id.bottle);
main.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
spinTheBottle();
}
});
Toast.makeText(this, R.string.touch_to_spin, Toast.LENGTH_SHORT).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.action_spin :
spinTheBottle();
break;
case R.id.action_zero :
resetTheBottle();
break;
}
return super.onOptionsItemSelected(item);
}
private void spinTheBottle() {
int angle = RANDOM.nextInt(3600 - 360) + 360;
float pivotX = bottle.getWidth() / 2;
float pivotY = bottle.getHeight() / 2;
final Animation animRotate = new RotateAnimation(lastAngle == -1 ? 0 : lastAngle, angle, pivotX, pivotY);
lastAngle = angle;
animRotate.setDuration(2500);
animRotate.setFillAfter(true);
bottle.startAnimation(animRotate);
}
private void resetTheBottle() {
float pivotX = bottle.getWidth() / 2;
float pivotY = bottle.getHeight() / 2;
final Animation animRotate = new RotateAnimation(lastAngle == -1 ? 0 : lastAngle, 0, pivotX, pivotY);
lastAngle = -1;
animRotate.setDuration(2000);
animRotate.setFillAfter(true);
bottle.startAnimation(animRotate);
}
}
You can run the application and play your game :
To go further, you can download the game “Spin The Bottle” created in this tutorial on the Google Play Store :
https://play.google.com/store/apps/details?id=com.ssaurel.spinthebottle
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Picture in Picture Mode (PinP) introduced on Android 8 (API 26) for All Android devices.
Its most used functionality is to shoa w preview of some data like Video Players, Maps & etc.
But there is also an option to add Custom Action & with this, you can do whatever you want to do.
This is Tutorial is about How to Add PinP for an Activity & Implementing Custom Actions to Create Shortcuts of Other Apps & Open Them
Click to expand...
Click to collapse
# Let Start #
What do you need to get started...
- Know How to Create Hello World Project
- Basic Info about Android Apps Files (.Java, .xml)/Components (Activity, Service)
Click to expand...
Click to collapse
What will you learn...
- Configure an Activity for PinP Mode
- Create PendingIntent
- Load Apps Info from PackageManager (AppName, AdaptiveIcons & etc)
- Load File Data in Lines
Click to expand...
Click to collapse
- Create new Android Studio Project, then open AndroidManifest.xml to add PinP attributes.
(I suggest to create specific Activity to handle PinP)
Code:
<activity
android:name=".PictureInPicture.PinP"
android:label="@string/title_activity_pin_p"
[B][COLOR="Blue"]android:resizeableActivity="true"
android:supportsPictureInPicture="true"[/COLOR][/B]
android:theme="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar" />
<!-- I used Wallpaper theme cause in my case I want to have transparent background that shows home launcher wallpaper -->
- Now Open your PinP Activity, PinP.java
The layout your design for this activity will show inside PinP Window.
(Here I set 3 ImageViews to load icons of selected apps that I load from a saved file)
To enter PinP Mode your need only to call this activity.enterPictureInPictureMode(); But you should add some functionality to it. READ COMMENTS IN CODE
Code:
public void enterPinP(){
[COLOR="Red"]//load packageNames from saved file[/COLOR]
List<String> appShortcutsPackageName = Arrays.asList(functionsClass.readFileLine(".autoSuper"));
[COLOR="red"]//set icon of apps to imageView[/COLOR]
imageViewOne.setImageBitmap(appIconBitmap(appShortcutsPackageName.get(0)));
imageViewTwo.setImageBitmap(appIconBitmap(appShortcutsPackageName.get(1)));
imageViewThree.setImageBitmap(appIconBitmap(appShortcutsPackageName.get(2)));
[COLOR="red"]//get main intent of apps[/COLOR]
Intent intentOne = getPackageManager().getLaunchIntentForPackage(appShortcutsPackageName.get(0)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent intentTwo = getPackageManager().getLaunchIntentForPackage(appShortcutsPackageName.get(1)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent intentThree = getPackageManager().getLaunchIntentForPackage(appShortcutsPackageName.get(2)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
[COLOR="red"]//create pending intent for actions on PinP Window [/COLOR]
[COLOR="red"]//you can also [b]getService()[/b] & [b]getBroadcast()[/b] [/COLOR]
final PendingIntent pendingIntentOne = PendingIntent.getActivity(getApplicationContext(), 333, intentOne,0);
final PendingIntent pendingIntentTwo = PendingIntent.getActivity(getApplicationContext(), 666, intentTwo,0);
final PendingIntent pendingIntentThree = PendingIntent.getActivity(getApplicationContext(), 999, intentThree,0);
[COLOR="red"]//here I add icon from resource to indicate where to click on PinP Window[/COLOR]
final Icon oneIcon = Icon.createWithResource(getApplicationContext(), R.drawable.ic_click);
final Icon twoIcon = Icon.createWithResource(getApplicationContext(), R.drawable.ic_click);
final Icon threeIcon = Icon.createWithResource(getApplicationContext(), R.drawable.ic_click);
[COLOR="red"]//remote actions to handle click from PinP Window[/COLOR]
final ArrayList<RemoteAction> remoteActions = new ArrayList<>();
remoteActions.add(new RemoteAction(oneIcon, appName(appShortcutsPackageName.get(0)), appName(appShortcutsPackageName.get(0)), pendingIntentOne));
remoteActions.add(new RemoteAction(twoIcon, appName(appShortcutsPackageName.get(1)), appName(appShortcutsPackageName.get(1)), pendingIntentTwo));
remoteActions.add(new RemoteAction(threeIcon, appName(appShortcutsPackageName.get(2)), appName(appShortcutsPackageName.get(2)), pendingIntentThree));
//
final PictureInPictureParams.Builder pictureInPictureParamsBuilder = new PictureInPictureParams.Builder();
pictureInPictureParamsBuilder.setActions(remoteActions);
pictureInPictureParamsBuilder.setAspectRatio(new Rational(50, 100));
PictureInPictureParams pictureInPictureParams = pictureInPictureParamsBuilder.build();
[B][COLOR="red"]//This is Main Functions. That you can Call from any Activity [/COLOR]
[COLOR="RoyalBlue"]enterPictureInPictureMode(pictureInPictureParams);[/COLOR][/B]
}
So wherever you call this function, it will enter to Picture in Picture Mode.
For Example, when click a button or @onPause() to continue showing some data.
I call it from onCreate(Bundle bundle) cause I create an activity specific for PinP Mode.
Also, you can recognize whenever your activity enter full screen mode Or PinP by overriding this functions
It is good way to add/remove views If you are using same activity for both full screen and PinP mode.
Code:
@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration configuration) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, configuration);
if (isInPictureInPictureMode){
//picture in picture mode
}
else {
//full screen mode
}
}
Note: Limited amount of RemoteActions can be set for PinP Mode that you can get it from activity.getMaxNumPictureInPictureActions();
Oo. Download | PinP Shortcuts .oO
Super Shortcuts | Available in Beta Stage
Feel Free to Ask for Promo Code
Thanks for Support my ProjectsDon't forget to Hit Thanks
PinP Shortcuts | Extra Functions
Extra Functions Used in Tutorial
Code:
public Bitmap [B]appIconBitmap[/B](String pack){
Bitmap bitmap = null;
try{
Drawable drawableIcon = context.getPackageManager().getApplicationIcon(pack);
if (drawableIcon instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable)drawableIcon).getBitmap();
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (drawableIcon instanceof AdaptiveIconDrawable){
Drawable backgroundDrawable = ((AdaptiveIconDrawable) drawableIcon).getBackground();
Drawable foregroundDrawable = ((AdaptiveIconDrawable) drawableIcon).getForeground();
Drawable[] drawables = new Drawable[2];
drawables[0] = backgroundDrawable;
drawables[1] = foregroundDrawable;
LayerDrawable layerDrawable = new LayerDrawable(drawables);
int width = layerDrawable.getIntrinsicWidth();
int height = layerDrawable.getIntrinsicHeight();
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
layerDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
layerDrawable.draw(canvas);
}
else{
bitmap = Bitmap.createBitmap(drawableIcon.getIntrinsicWidth(), drawableIcon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
}
else{
bitmap = Bitmap.createBitmap(drawableIcon.getIntrinsicWidth(), drawableIcon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
}
catch(Exception e){
e.printStackTrace();
}
return bitmap;
}
Code:
public String [B]appName[/B](String pack){
String Name = null;
try{
PackageManager packManager = context.getPackageManager();
ApplicationInfo app = context.getPackageManager().getApplicationInfo(pack, 0);
Name = packManager.getApplicationLabel(app).toString();
}
catch(Exception e){
e.printStackTrace();
}
return Name;
}
Thanks for Support my ProjectsDon't forget to Hit Thanks
Reserved