diff options
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/ThemeTests/cm11_to_cm12/downgrade_to_cm11.sh | 34 | ||||
-rw-r--r-- | tests/ThemesTest/Android.mk | 19 | ||||
-rw-r--r-- | tests/ThemesTest/AndroidManifest.xml | 21 | ||||
-rw-r--r-- | tests/ThemesTest/res/drawable-hdpi/test_wallpaper_thumb.png | bin | 0 -> 34700 bytes | |||
-rw-r--r-- | tests/ThemesTest/res/layout/activity_main.xml | 48 | ||||
-rw-r--r-- | tests/ThemesTest/res/layout/theme_list_item.xml | 14 | ||||
-rw-r--r-- | tests/ThemesTest/res/values-v11/styles.xml | 28 | ||||
-rw-r--r-- | tests/ThemesTest/res/values-v21/styles.xml | 29 | ||||
-rw-r--r-- | tests/ThemesTest/res/values/strings.xml | 22 | ||||
-rw-r--r-- | tests/ThemesTest/res/values/styles.xml | 37 | ||||
-rw-r--r-- | tests/ThemesTest/src/com/example/themetests/MainActivity.java | 326 |
11 files changed, 578 insertions, 0 deletions
diff --git a/tests/ThemeTests/cm11_to_cm12/downgrade_to_cm11.sh b/tests/ThemeTests/cm11_to_cm12/downgrade_to_cm11.sh new file mode 100755 index 0000000..9f8a2c6 --- /dev/null +++ b/tests/ThemeTests/cm11_to_cm12/downgrade_to_cm11.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +#**************************************************************************************** +# Run this script to move your CM12 device move back to a CM11 state. This is +# useful when you want to manually test CM11 to CM12 upgrade without reflashing the device +#*************************************************************************************** + +#Delete all themes related data +adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "DELETE FROM secure WHERE name='themeConfig'"; +adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "DELETE FROM secure WHERE name='theme_prev_boot_api_level'"; +adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "pragma user_version=115" +adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "DELETE FROM secure WHERE name='default_theme_package'" +adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "DELETE FROM secure WHERE name='default_theme_components'" + +#HEXO Config (Comment HOLO if you use this) +adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO secure (name,value) VALUES('themeConfig','{\"default\":{\"mOverlayPkgName\":\"com.cyngn.hexo\",\"mIconPkgName\":\"com.tung91.mianogen\",\"mFontPkgName\":\"bigwave.thyrus.darkuinte\"}}')"; + +#HOLO Config (Comment HEXO if you use this) +#adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO secure (name,value) VALUES('themeConfig','{\"default\":{\"mOverlayPkgName\":\"holo\",\"mIconPkgName\":\"com.tung91.mianogen\",\"mFontPkgName\":\"bigwave.thyrus.darkuinte\"}}')"; + + +#Default Theme Package +adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO secure (name,value) VALUES('default_theme_package', 'com.cyngn.hexo')" +adb shell 'sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO secure (name,value) VALUES(\"default_theme_components\", \"mods_overlays\")"' + +#Print out the db +adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "SELECT * from secure" + + +#ThemesProvider's default theme is called "Holo" +adb shell sqlite3 /data/data/org.cyanogenmod.themes.provider/databases/themes.db "UPDATE themes SET pkg_name='holo', title='Holo' WHERE pkg_name='system'" +adb shell sqlite3 /data/data/org.cyanogenmod.themes.provider/databases/themes.db "pragma user_version=10" + +adb shell sqlite3 /data/data/org.cyanogenmod.themes.provider/databases/themes.db "SELECT * FROM themes" diff --git a/tests/ThemesTest/Android.mk b/tests/ThemesTest/Android.mk new file mode 100644 index 0000000..faddddb --- /dev/null +++ b/tests/ThemesTest/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := ThemeTest + +LOCAL_PROGUARD_ENABLED := disabled + +LOCAL_CERTIFICATE := platform + +LOCAL_PRIVILEGED_MODULE := true + +include $(BUILD_PACKAGE) + diff --git a/tests/ThemesTest/AndroidManifest.xml b/tests/ThemesTest/AndroidManifest.xml new file mode 100644 index 0000000..1357aba --- /dev/null +++ b/tests/ThemesTest/AndroidManifest.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.themetests" > + + <uses-permission android:name="android.permission.ACCESS_THEME_MANAGER" /> + <uses-permission android:name="android.permission.READ_THEMES" /> + <uses-permission android:name="android.permission.WRITE_THEMES" /> + + <application + 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> + </application> +</manifest> diff --git a/tests/ThemesTest/res/drawable-hdpi/test_wallpaper_thumb.png b/tests/ThemesTest/res/drawable-hdpi/test_wallpaper_thumb.png Binary files differnew file mode 100644 index 0000000..df92eb5 --- /dev/null +++ b/tests/ThemesTest/res/drawable-hdpi/test_wallpaper_thumb.png diff --git a/tests/ThemesTest/res/layout/activity_main.xml b/tests/ThemesTest/res/layout/activity_main.xml new file mode 100644 index 0000000..d6098ba --- /dev/null +++ b/tests/ThemesTest/res/layout/activity_main.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ListView + android:id="@+id/theme_list" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:divider="@android:color/transparent" + android:dividerHeight="0dp"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="48dp" + android:orientation="horizontal" + android:layout_gravity="center_horizontal" + android:gravity="center"> + + <ImageView + android:id="@+id/icon" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:gravity="center"/> + + <ImageView + android:id="@+id/image" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:gravity="center"/> + + </LinearLayout> + + <Button + android:id="@+id/detach_assets" + android:layout_width="match_parent" + android:layout_height="64dp" + android:layout_gravity="center_horizontal" + android:gravity="center" + android:textSize="24dp" + android:text="@string/detach_assets" + android:enabled="false"/> + +</LinearLayout> diff --git a/tests/ThemesTest/res/layout/theme_list_item.xml b/tests/ThemesTest/res/layout/theme_list_item.xml new file mode 100644 index 0000000..f7b56c2 --- /dev/null +++ b/tests/ThemesTest/res/layout/theme_list_item.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" android:layout_width="match_parent" + android:layout_height="64dp"> + + <TextView + android:id="@+id/theme_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:layout_gravity="center_horizontal" + android:textSize="48dp" /> + +</LinearLayout>
\ No newline at end of file diff --git a/tests/ThemesTest/res/values-v11/styles.xml b/tests/ThemesTest/res/values-v11/styles.xml new file mode 100644 index 0000000..8e4857c --- /dev/null +++ b/tests/ThemesTest/res/values-v11/styles.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2013 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<resources> + + <!-- + Base application theme for API 11+. This theme completely replaces + AppBaseTheme from res/values/styles.xml on API 11+ devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Holo"> + <!-- API 11 theme customizations can go here. --> + </style> + +</resources>
\ No newline at end of file diff --git a/tests/ThemesTest/res/values-v21/styles.xml b/tests/ThemesTest/res/values-v21/styles.xml new file mode 100644 index 0000000..0454ba1 --- /dev/null +++ b/tests/ThemesTest/res/values-v21/styles.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2013 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<resources> + + <!-- + Base application theme for API 21+. This theme completely replaces + AppBaseTheme from BOTH res/values/styles.xml and + res/values-v11/styles.xml on API 14+ devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Material"> + <!-- API 14 theme customizations can go here. --> + </style> + +</resources>
\ No newline at end of file diff --git a/tests/ThemesTest/res/values/strings.xml b/tests/ThemesTest/res/values/strings.xml new file mode 100644 index 0000000..59bebfc --- /dev/null +++ b/tests/ThemesTest/res/values/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2014 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<resources> + <string name="app_name">Theme Test</string> + + <string name="detach_assets">Detach theme assets</string> +</resources> diff --git a/tests/ThemesTest/res/values/styles.xml b/tests/ThemesTest/res/values/styles.xml new file mode 100644 index 0000000..501678a --- /dev/null +++ b/tests/ThemesTest/res/values/styles.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2013 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<resources> + + <!-- + Base application theme, dependent on API level. This theme is replaced + by AppBaseTheme from res/values-vXX/styles.xml on newer devices. + --> + <style name="AppBaseTheme" parent="android:Theme"> + <!-- + Theme customizations available in newer API levels can go in + res/values-vXX/styles.xml, while customizations related to + backward-compatibility can go here. + --> + </style> + + <!-- Application theme. --> + <style name="AppTheme" parent="AppBaseTheme"> + <!-- All customizations that are NOT specific to a particular API-level can go here. --> + </style> + +</resources>
\ No newline at end of file diff --git a/tests/ThemesTest/src/com/example/themetests/MainActivity.java b/tests/ThemesTest/src/com/example/themetests/MainActivity.java new file mode 100644 index 0000000..2793272 --- /dev/null +++ b/tests/ThemesTest/src/com/example/themetests/MainActivity.java @@ -0,0 +1,326 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.themetests; + +import android.app.Activity; +import android.app.ComposedIconInfo; +import android.content.Context; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageManager; +import android.content.pm.PackageInfo; +import android.content.pm.PackageItemInfo; +import android.content.pm.PackageManager; +import android.content.pm.ThemeUtils; +import android.content.res.AssetManager; +import android.content.res.Resources; +import android.content.res.ThemeConfig; +import android.database.Cursor; +import android.os.Bundle; + +import android.os.ServiceManager; +import android.provider.ThemesContract.ThemesColumns; +import android.text.TextUtils; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.CursorAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.TextView; + +import java.util.List; + +public class MainActivity extends Activity { + private static final String TAG = "MainActivity"; + + private ListView mThemeList; + private Button mDetachButton; + private ImageView mImage; + private ImageView mIcon; + + private Resources mResources; + private AssetManager mAssets; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + mThemeList = (ListView) findViewById(R.id.theme_list); + mDetachButton = (Button) findViewById(R.id.detach_assets); + mDetachButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + detachThemeAssets(mResources, mAssets); + mThemeList.setEnabled(true); + mDetachButton.setEnabled(false); + updateImages(); + } + }); + mImage = (ImageView) findViewById(R.id.image); + mIcon = (ImageView) findViewById(R.id.icon); + } + + @Override + protected void onResume() { + super.onResume(); + PackageManager pm = getPackageManager(); + Context ctx = null; + try { + ctx = createPackageContext("com.android.systemui", 0); + mAssets = ctx.getAssets(); + mResources = ctx.getResources(); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + + updateImages(); + loadThemes(); + } + + private void loadThemes() { + String[] columns = {ThemesColumns._ID, ThemesColumns.TITLE, ThemesColumns.PKG_NAME}; + String selection = ThemesColumns.PRESENT_AS_THEME + "=? AND " + + ThemesColumns.PKG_NAME + "<>?"; + String[] selectionArgs = {"1", ThemeConfig.SYSTEM_DEFAULT}; + Cursor c = getContentResolver().query(ThemesColumns.CONTENT_URI, columns, selection, + selectionArgs, null); + if (c != null) { + ThemeAdapter adapter = new ThemeAdapter(this, c, 0); + mThemeList.setAdapter(adapter); + mThemeList.setOnItemClickListener(mThemeClicked); + } + } + + private boolean attachThemeAssets(Resources res, AssetManager assets, String pkgName) { + final PackageManager pm = getPackageManager(); + PackageInfo piTheme = null; + PackageInfo piAndroid = null; + PackageInfo piTarget = null; + PackageInfo piIcon = null; + + String basePackageName = null; + int count = assets.getBasePackageCount(); + if (count > 1) { + basePackageName = assets.getBasePackageName(1); + } else if (count == 1) { + basePackageName = assets.getBasePackageName(0); + } else { + return false; + } + + try { + piTheme = pm.getPackageInfo(pkgName, 0); + piAndroid = getPackageManager().getPackageInfo("android", 0); + piTarget = getPackageManager().getPackageInfo(basePackageName, 0); + piIcon = getPackageManager().getPackageInfo(pkgName, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + + if (piTheme == null || piTheme.applicationInfo == null || + piAndroid == null || piAndroid.applicationInfo == null || + piTheme.mOverlayTargets == null) { + return false; + } + + String themePackageName = pkgName; + String themePath = piTheme.applicationInfo.publicSourceDir; + if (!piTarget.isThemeApk && piTheme.mOverlayTargets.contains(basePackageName)) { + String targetPackagePath = piTarget.applicationInfo.sourceDir; + String prefixPath = ThemeUtils.getOverlayPathToTarget(basePackageName); + + String resCachePath = ThemeUtils.getResDir(basePackageName, piTheme); + String resTablePath = resCachePath + "/resources.arsc"; + String resApkPath = resCachePath + "/resources.apk"; + int cookie = assets.addOverlayPath(themePath, resTablePath, resApkPath, + targetPackagePath, prefixPath); + + if (cookie != 0) { + assets.setThemePackageName(themePackageName); + assets.addThemeCookie(cookie); + } + } + + if (!piTarget.isThemeApk && piTheme.mOverlayTargets.contains("android")) { + String resCachePath= ThemeUtils.getResDir(piAndroid.packageName, piTheme); + String prefixPath = ThemeUtils.getOverlayPathToTarget(piAndroid.packageName); + String targetPackagePath = piAndroid.applicationInfo.publicSourceDir; + String resTablePath = resCachePath + "/resources.arsc"; + String resApkPath = resCachePath + "/resources.apk"; + int cookie = assets.addOverlayPath(themePath, resTablePath, + resApkPath, targetPackagePath, prefixPath); + if (cookie != 0 && !assets.getThemeCookies().contains(cookie)) { + assets.setThemePackageName(themePackageName); + assets.addThemeCookie(cookie); + } + } + + if (piIcon != null) { + String themeIconPath = piIcon.applicationInfo.publicSourceDir; + String prefixPath = ThemeUtils.ICONS_PATH; + String iconDir = ThemeUtils.getIconPackDir(pkgName); + String resTablePath = iconDir + "/resources.arsc"; + String resApkPath = iconDir + "/resources.apk"; + + // Legacy Icon packs have everything in their APK + if (piIcon.isLegacyIconPackApk) { + prefixPath = ""; + resApkPath = ""; + resTablePath = ""; + } + + int cookie = assets.addIconPath(themeIconPath, resTablePath, resApkPath, prefixPath, + Resources.THEME_ICON_PKG_ID); + if (cookie != 0) { + assets.setIconPackCookie(cookie); + assets.setIconPackageName(pkgName); + setActivityIcons(res); + } + } + + res.updateStringCache(); + return true; + } + + private void detachThemeAssets(Resources res, AssetManager assets) { + String themePackageName = assets.getThemePackageName(); + String iconPackageName = assets.getIconPackageName(); + String commonResPackageName = assets.getCommonResPackageName(); + + //Remove Icon pack if it exists + if (!TextUtils.isEmpty(iconPackageName) && assets.getIconPackCookie() > 0) { + assets.removeOverlayPath(iconPackageName, assets.getIconPackCookie()); + assets.setIconPackageName(null); + assets.setIconPackCookie(0); + } + //Remove common resources if it exists + if (!TextUtils.isEmpty(commonResPackageName) && assets.getCommonResCookie() > 0) { + assets.removeOverlayPath(commonResPackageName, assets.getCommonResCookie()); + assets.setCommonResPackageName(null); + assets.setCommonResCookie(0); + } + final List<Integer> themeCookies = assets.getThemeCookies(); + if (!TextUtils.isEmpty(themePackageName) && !themeCookies.isEmpty()) { + // remove overlays in reverse order + for (int i = themeCookies.size() - 1; i >= 0; i--) { + assets.removeOverlayPath(themePackageName, themeCookies.get(i)); + } + } + assets.getThemeCookies().clear(); + assets.setThemePackageName(null); + //res.updateStringCache(); + } + + private void setActivityIcons(Resources r, String themePkgName) { + SparseArray<PackageItemInfo> iconResources = new SparseArray<PackageItemInfo>(); + String pkgName = r.getAssets().getAppName(); + PackageInfo pkgInfo = null; + ApplicationInfo appInfo = null; + + try { + pkgInfo = getPackageManager().getPackageInfo(pkgName, PackageManager.GET_ACTIVITIES); + } catch (PackageManager.NameNotFoundException e) { + return; + } + + final ThemeConfig themeConfig = r.getConfiguration().themeConfig; + if (pkgName != null && themeConfig != null && + pkgName.equals(themeConfig.getIconPackPkgName())) { + return; + } + + //Map application icon + if (pkgInfo != null && pkgInfo.applicationInfo != null) { + appInfo = pkgInfo.applicationInfo; + if (appInfo.themedIcon != 0 || iconResources.get(appInfo.icon) == null) { + iconResources.put(appInfo.icon, appInfo); + } + } + + //Map activity icons. + if (pkgInfo != null && pkgInfo.activities != null) { + for (ActivityInfo ai : pkgInfo.activities) { + if (ai.icon != 0 && (ai.themedIcon != 0 || iconResources.get(ai.icon) == null)) { + iconResources.put(ai.icon, ai); + } else if (appInfo != null && appInfo.icon != 0 && + (ai.themedIcon != 0 || iconResources.get(appInfo.icon) == null)) { + iconResources.put(appInfo.icon, ai); + } + } + } + + r.setIconResources(iconResources); + final IPackageManager pm = IPackageManager.Stub.asInterface( + ServiceManager.getService("package")); + try { + ComposedIconInfo iconInfo = pm.getComposedIconInfo(); + r.setComposedIconInfo(iconInfo); + } catch (Exception e) { + } + } + + AdapterView.OnItemClickListener mThemeClicked = new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + String pkgName = (String) view.getTag(); + if (attachThemeAssets(mResources, mAssets, pkgName)) { + mThemeList.setEnabled(false); + mDetachButton.setEnabled(true); + updateImages(); + } + } + }; + + private void updateImages() { + int resId = mResources.getIdentifier("ic_sysbar_home", "drawable", "com.android.systemui"); + if (resId != 0) { + mImage.setImageDrawable(mResources.getDrawable(resId)); + } + resId = mResources.getIdentifier("icon", "drawable", "com.android.systemui"); + if (resId != 0) { + mIcon.setImageDrawable(mResources.getDrawable(resId)); + } + } + + class ThemeAdapter extends CursorAdapter { + public ThemeAdapter(Context context, Cursor c, int flags) { + super(context, c, flags); + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + LayoutInflater inflater = getLayoutInflater(); + View v = inflater.inflate(R.layout.theme_list_item, parent, false); + return v; + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + int titleIdx = cursor.getColumnIndex(ThemesColumns.TITLE); + int pkgIdx = cursor.getColumnIndex(ThemesColumns.PKG_NAME); + String title = cursor.getString(titleIdx); + String pkgName = cursor.getString(pkgIdx); + TextView tv = (TextView) view.findViewById(R.id.theme_title); + tv.setText(title); + view.setTag(pkgName); + } + } +} |