[Java for Android App Development] mikrosmile:
HTC Carousel Activity/Fragment (Swipeable tabs) - Sense 3.6 up to Sense 6 Samples

HTC Carousel with Tabs for Sense 3.6 up to Sense 4 (Using Activities)

Create classes and Carousel (HTC Sense Tabs)

Create simple activities

Create two classes Tab1.java; Tab2.java

Create two layout xml files - tab_1.xml; tab_2.xml;

Place any two different png icons for Tab1 and Tab2 reference

tab_1.xml

<RelativeLayout 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"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is Tab1" />

</RelativeLayout>

tab_2.xml

<RelativeLayout 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"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is Tab2" />

</RelativeLayout>

Tab1.java

package com.yourpackage.name;

import android.app.Activity;
import android.os.Bundle;

public class Tab1 extends Activity {

[MENTION=439709]override[/MENTION]
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_1);
}

}

Tab2.java

package com.yourpackage.name;

import android.app.Activity;
import android.os.Bundle;

public class Tab2 extends Activity {

[MENTION=439709]override[/MENTION]
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_2);
}

}

Create carousel (HTC Sense Tabs) and put tabs together

Create class: TabProvider.java; Remove everything inside class and place this code:

com.yourpackage.name - it is your name of package.

TabProvider.java

package com.yourpackage.name;

import com.htc.content.CarouselProvider;

[MENTION=1299008]supp[/MENTION]ressWarnings("deprecation")
public class TabProvider extends CarouselProvider {
final static String AUTHORITY =
"com.yourpackage.name.TabProvider";

public TabProvider() {
super();
setupCarousel(AUTHORITY);

}

}

Open MainActivity, remove everything from class and paste this code:

MainActivity.java

package com.yourpackage.name;

import android.content.Intent;
import android.os.Bundle;
import com.htc.widget.CarouselActivity;
import com.htc.widget.CarouselHost;

public class MainActivity extends CarouselActivity {
final static String AUTHORITY =
"com.yourpackage.name.TabProvider";

public MainActivity() {
super(AUTHORITY);
}

[MENTION=439709]override[/MENTION]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setGId(1);
super.onCreate(savedInstanceState);
final CarouselHost mPanelHost = getCarouselHost();

mPanelHost.addTab("Tab1", this, R.string.tab_1,
R.drawable.ic_tab1,
R.drawable.ic_tab1,
R.drawable.ic_tab1,
(new Intent("com.yourpackage.name.Tab1")));
mPanelHost.addTab("Tab2", this, R.string.tab_2,
R.drawable.ic_tab2,
R.drawable.ic_tab2,
R.drawable.ic_tab2,
(new Intent("com.yourpackage.name.Tab2")));
}

}

Configuring manifest

Dont forget, all classes have to be in Manifest.

<activity
android:name=".Tab1"
android:screenOrientation="portrait"
android:configChanges="orientation"
android:label="Tab1" >
<intent-filter>
<action android:name="com.yourpackage.name.Tab1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".Tab2"
android:screenOrientation="portrait"
android:configChanges="orientation"
android:label="Tab2" >
<intent-filter>
<action android:name="com.yourpackage.name.Tab2" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

Also for HTC SDK you have to state Provider: Create provider at the end of Manifest before </application> tag

<provider
android:name="com.yourpackage.name.TabProvider"
android:authorities="com.yourpackage.name.TabProvider" />

Create ActionBar in HTC Sense Style

For all tabs in your main activity you dont need to create actionbar for each of them, you need only one Actionbar for all Tabs.

That means all Activities which will be part of TabCarousel it will use the same action bar from MainActivity.

Make Changes in your mainactivity as follow:

MainActivity.java with ActionBar

package com.yourpackage.name;

import android.content.Intent;
import android.os.Bundle;
import com.htc.widget.CarouselActivity;
import com.htc.widget.CarouselHost;
[COLOR="Red"]import com.htc.widget.ActionBarExt;
import com.htc.widget.ActionBarText;[/COLOR]

public class MainActivity extends CarouselActivity {
final static String AUTHORITY =
"com.yourpackage.name.TabProvider";
[COLOR="red"]public static ActionBarText mActionText;[/COLOR]

public MainActivity() {
super(AUTHORITY);
}

[COLOR="red"] private void SetupActionBar()
{
Object obj = new ActionBarExt(this, getActionBar());
((ActionBarExt)obj).setFullScreenEnabled(true);
((ActionBarExt)obj).enableHTCLandscape(false);
mActionText = new ActionBarText(this);
mActionText.setPrimaryText(R.string.app_name);
obj = ((ActionBarExt)obj).getCustomContainer();
((ActionBarContainer)obj).setRightDividerEnabled(true);
((ActionBarContainer)obj).addCenterView(mActionText);
}[/COLOR]

[MENTION=439709]override[/MENTION]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setGId(1);
super.onCreate(savedInstanceState);
final CarouselHost mPanelHost = getCarouselHost();
[COLOR="red"]SetupActionBar();[/COLOR]

mPanelHost.addTab("Tab1", this, R.string.tab_1,
R.drawable.ic_tab1,
R.drawable.ic_tab1,
R.drawable.ic_tab1,
(new Intent("com.yourpackage.name.Tab1")));
mPanelHost.addTab("Tab2", this, R.string.tab_2,
R.drawable.ic_tab2,
R.drawable.ic_tab2,
R.drawable.ic_tab2,
(new Intent("com.yourpackage.name.Tab2")));
}

}

HTC Carousel with Tabs for Sense 4.1 up to Sense 5.5 (Using Fragments)

Create Carousel Fragment, Tabs, MainActivity

Create Tab Fragments

Now instead of Activities we will use Fragments, and it is difficult for some users. And I will try to explain how to build Carousel and not how to build Fragment Activity. But as example you can refer to my Open Source project myStore (which now converted to Fragments)

Create two classes Tab1Fragment and Tab2Fragment

Tab1Fragment.java

package your.package.name;

[COLOR="Lime"]#2[/COLOR] import android.app.Fragment;

[COLOR="lime"]#1[/COLOR] public class Tab1Fragment [B][COLOR="red"]extends Fragment[/COLOR][/B] {
Button button;

[COLOR="lime"]#3[/COLOR] public Tab1Fragment () {
}

[COLOR="lime"]#4[/COLOR] [MENTION=439709]override[/MENTION]
public [B][COLOR="Red"]View onCreateView[/COLOR][/B](LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab1, container, false);
[COLOR="Lime"]#7[/COLOR] button = (Button) [B][COLOR="Red"]view.[/COLOR][/B]findViewById(R.id.button);
[COLOR="RoyalBlue"][I]//All your code that you need when application is first time created (see onCreate method example)[/I][/COLOR]

[COLOR="lime"]#5[/COLOR] [B][COLOR="red"]return view;[/COLOR][/B]
}

[COLOR="lime"]#6[/COLOR]
}

As you can see the Class structure is different from what you might get used.

Now you need to extend class as Fragment (#1) and import android.app.Fragment; (#2)

Then you need to have public method which represent the entire Class with the name of the Class (#3)

And Fragment uses onCreateView method instead of onCreate in Activity (#4)

And you also need return statement for the view (#5) which will be at the end after all your code inside onCreateView method

Outside onCreateView you will have all your methods for the purpose of application and those methods you will call from onCreateView method.

Example of (#7) is that how you need to use findViewById method. you need to add view. before the method. Other than tha is the same

Now create Tab2Fragment and use the same method but different layout resources.

Create Tab Provider

package your.package.name;

import com.htc.fragment.content.CarouselProvider;

public class TabProvider extends CarouselProvider {
public TabProvider(){
super();
setupCarousel(MainActivity.AUTHORITY);
}

}

Create CarouselFragment

Now to store tabs in your application we will use separate Carousel class where you will identify each tab, name, Class, icons , etc

For each tab create method for it for example

private void addTab1(CarouselHost host, String tag, int icon, int str) {
host.addTab(getActivity(), new CarouselTabSpec(tag,
str, icon, icon, icon, Tab1Fragment.class.getName()));
}

private void addAnotherTab(CarouselHost host, String tag, int icon, int str) {
host.addTab(getActivity(), new CarouselTabSpec(tag,
str, icon, icon, icon, AnotherTabFragment.class.getName()));
}

and in onActivityCreated method add your tab as in example

addAnotherTab(host, "AnotherTab", R.drawable.another_icon,
R.string.another_tab);

Carousel.java

package your.package.name;

import android.os.Bundle;

import com.htc.fragment.widget.CarouselFragment;
import com.htc.fragment.widget.CarouselHost;
import com.htc.fragment.widget.CarouselTabSpec;

public class Carousel extends CarouselFragment {

public Carousel() {
super(MainActivity.AUTHORITY);
requestCarouselFeature(CarouselFragment.FEATURE_CUSTOM_TITLE);
}

private void addTab1(CarouselHost host, String tag, int icon, int str) {
host.addTab(getActivity(), new CarouselTabSpec(tag,
str, icon, icon, icon, Tab1Fragment.class.getName()));
}

private void addTab2(CarouselHost host, String tag, int icon, int str) {
host.addTab(getActivity(), new CarouselTabSpec(tag,
str, icon, icon, icon, Tab2Fragment.class.getName()));
}

[MENTION=439709]override[/MENTION]
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

final CarouselHost host = getCarouselHost();

addTab1(host, "Tab1", R.drawable.ic_tab1,
R.string.tab1);
addTab2(host, "Tab2", R.drawable.ic_tab2,
R.string.tab2);
}

}

Create MainActivity

Now MainActivity will be simple Activity with reference to Carousel class.

package your.package.name;

public class MainActivity extends Activity {
final static String AUTHORITY = "your.package.name.MainActivity";
private Carousel mCarousel = null;

public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
final int rootId = 1;
FrameLayout viewRoot = new FrameLayout(this);
viewRoot.setId(rootId);
setContentView(viewRoot);
mCarousel = new Carousel();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(rootId, mCarousel);
ft.commit();
registerForContextMenu(viewRoot);
}
}

Configuration of Manifest

For Fragments you dont need anymore to add permission for them in Manifest (Only for Activities)

So basically with One mainactivity and two Tabs your manifest should look like

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.package.name"
android:versionCode="10"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="17" />

<application
android:allowBackup="true"
allowSkinChange="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="your.package.name.MainActivity"
android:screenOrientation="portrait"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="your.package.name.TabProvider"
android:authorities="your.package.name.MainActivity" />
</application>

</manifest>

Make sure your provider is exaclty as follow.​

HTC Carousel with Tabs for Sense 6 (Using Fragments)

Create CarouselFragment, MainActivity, Tabs

CarouselFragment:

package com.your.pkg;

[COLOR="red"]import com.htc.fragment.widget.CarouselFragment; <!-- Make sure the imports from com.htc.fragment.*-->
import com.htc.fragment.widget.CarouselHost;
import com.htc.fragment.widget.CarouselTabSpec;[/COLOR]

importcom.your.pkg.MainActivity;
import com.your.pkg.R;
import android.os.Bundle;

public class Carousel extends [COLOR="Red"]CarouselFragment[/COLOR] {

public Carousel() {
super(MainActivity.AUTHORITY);
requestCarouselFeature(CarouselFragment.FEATURE_CUSTOM_TITLE);

}

private void addTab(CarouselHost host, String tag, int icon, int str, String tag5) {
host.addTab(getActivity(), new CarouselTabSpec(tag,
str, tag5));

}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

final CarouselHost host = getCarouselHost();

addTab(host, [COLOR="Blue"]"FirstTab"[/COLOR], R.drawable.ic_launcher,
R.string.[COLOR="Blue"]first[/COLOR], First.class.getName());

addTab(host, [COLOR="Blue"]"SecondTab"[/COLOR], R.drawable.ic_launcher,
R.string.[COLOR="Blue"]second[/COLOR], Second.class.getName());

[COLOR="Red"]<!-- Add as many addTab(); methods as you need Tabs. The addTab() is universal-->[/COLOR]

}
}

MainActivity

public class MainActivity extends MfMainActivity {
public final static String AUTHORITY = "mikrosmile.kontrol.MainActivity";

private Carousel mCarousel = null;
static Window window;

@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
super.onCreate(savedInstanceState);

final int rootId = 1;
FrameLayout viewRoot = new FrameLayout(this);
viewRoot.setId(rootId);
setContentView(viewRoot);
mCarousel = new Carousel();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(rootId, mCarousel);
ft.commit();
registerForContextMenu(viewRoot);
getWindow().setFormat(1);

}

}

Tabs

Any Activity or Fragment

HTC's Release to Refresh method (Swipe2Refresh)

The Release to Refresh is like this:

View attachment 2711413

It can be added to any View. I will show example how to add it to ListView

[COLOR="red"]import com.htc.widget.OnPullDownListener;[/COLOR]
public static ActionBarRefresh aRefresh;

@Override
protected void onCreate(Bundle bundle) {
//Adding inside onCreate method of you listActivity
list.[COLOR="Red"]setOnPullDownListener(new PullDown());[/COLOR]

}

public class PullDown implements OnPullDownListener{
//just a class inside your listActivity

@Override
public void onGapChanged(int top, int bottom) {
if(top != 0){
actionbarext.getCustomContainer().setRotationMax(top);
actionbarext.getCustomContainer().setRotationProgress(bottom);
//actionbarext.getCustomContainer is your ActionBar container
}
}

@Override
public void onPullDownCancel() {
actionbarext.getCustomContainer().setUpdatingState(0);
}

@Override
public void onPullDownRelease() {
actionbarext.getCustomContainer().setUpdatingState(0);
//do whatever you need to update the list here, you can call a method or AsyncTask from here

}

@Override
public void onPullDownToBoundary() {
actionbarext.getCustomContainer().setRotationProgress(actionbarext.getCustomContainer().getRotationMax());
}

}

On your method to update list add this to onPreExecute

aRefresh.setVisibility(View.VISIBLE);
aRefresh.setPrimaryText("Updating...");
actionbartext.setPrimaryVisibility(View.GONE);
actionbartext.setSecondaryVisibility(View.GONE);

When you finish your task to update list, inside onPostExecute add this

actionbarext.getCustomContainer().setUpdatingState(0);

Inside your method to SetupActionBar add this

aRefresh = new ActionBarRefresh(c);
aRefresh.setVisibility(View.GONE);
actionbarext.getCustomContainer().addCenterView(aRefresh);

​

Add HTC Sense 6 Theme support to your app

Inside your MainActivity add this method

public static int getHtcThemeID(Context context, int i)
{
return HtcWrapConfiguration.getHtcThemeId(context, i);

}

And in onCreate method add this

setTheme(getHtcThemeID(context, 0));

This method is returning current Choosen theme ID by Variable from 0 to 3.

So, when you open Personalization - Theme. You see 4 Themes. First 3 has different Color boxes at the top. The first 3 is the actual variable integer from 0 - 3.

So, if you want to get , let's say Red color from Theme 2. You have to Choose Theme 2 in the Theme Settings, and in the app use this:

setTheme(getHtcThemeID(context, 3));

Once you change Theme, it will also use The Orange color from Theme 1, and the Purple Color from Theme 3

​

Add SlidingMenu to your Sense application

To make the sliding menu in your application like Mail app or File manager app, follow this:

View attachment 2876504

public class MainActivity extends [COLOR="Red"]SlidingActivity [/COLOR]{
[COLOR="red"]private SlidingMenu mSlidingMenu;[/COLOR]

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
window = getWindow();
setContentView(R.layout.activity_main);
[COLOR="red"]setBehindContentView(R.layout.activity_behind);
initSlidingMenu();[/COLOR]
SetupActionBar(this);

}

private void initSlidingMenu()
{
mSlidingMenu = getSlidingMenu();
[COLOR="red"]mSlidingMenu.setBehindWidth(500);[/COLOR] [COLOR="Lime"]//any width as you want[/COLOR]
mSlidingMenu.setFadeDegree(0.5F);
mSlidingMenu.setFadeEnabled(true);
mSlidingMenu.setMode(0);
mSlidingMenu.setTouchModeAbove(0);
mSlidingMenu.setOnOpenedListener(new com.htc.widget.SlidingMenu.OnOpenedListener() {

public void onOpened()
{
initSlidingMenuContent();
}
});
}

private void initSlidingMenuContent(){
[COLOR="red"] mSlidingMenu.setShadowWidth(50);
mSlidingMenu.setShadowDrawable(ICservices.getShadowDrawable());[/COLOR][COLOR="Lime"]//any shadow drawable you want
//here is all your code that represent the behind layout. it can be listview or any other View you need[/COLOR]
}

[COLOR="SeaGreen"]//if you want to have a toggle at the actionbar, also add OnClickListener to ActionbarTextView and add IconView to Actionbar[/COLOR]

}

add this permission to Manifest:
[COLOR="red"]<uses-permission android:name="com.htc.permission.APP_DEFAULT" />[/COLOR]