@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
holder = createViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
IModel model = getGroup(groupPosition);
holder.text1.setText(model.getText1());
holder.layout.setBackgroundColor(context.getBackgroundColor(model));
return convertView;
}
private ViewHolder createViewHolder(View convertView) {
ViewHolder holder;
holder = new ViewHolder();
holder.text1 = (TextView) convertView.findViewById(R.id.row_text1);
holder.layout = (LinearLayout) convertView.findViewById(R.id.layoutRow);
return holder;
}
viernes, 25 de julio de 2014
Android: Smooth scrolling tricks (ListView)
Android: ImageView wrap resized image.
getWomanPictureView().getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Bitmap image = getFragment().getWomanPictureBitmap(
getWomanPictureView(), "fotito_normal");
getWomanPictureView().setImageBitmap(image);
removeOnGlobalLayoutListener(getWomanPictureView());
}
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void removeOnGlobalLayoutListener(
final ImageView image) {
int currentAPIVersion = android.os.Build.VERSION.SDK_INT;
if (currentAPIVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
image.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
} else {
image.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
}
});
public Bitmap getWomanPictureBitmap(ImageView womanPictureView,
String womanPicture) {
int womanPictureResID = getActivity().getResources().getIdentifier(
womanPicture, "drawable", getActivity().getPackageName());
Bitmap image = BitmapFactory.decodeResource(getResources(),
womanPictureResID);
int width = womanPictureView.getWidth();
if (width != 0 && width != image.getWidth()) {
int height = width * image.getHeight() / image.getWidth();
Bitmap scaledImage = Bitmap.createScaledBitmap(image, width,
height, false);
image.recycle();
return scaledImage;
} else {
return image;
}
}
martes, 22 de julio de 2014
Android: Custom action bar
Using sherlock:
Manifest
Activity
Using appcompat
Manifest
Activity
Manifest
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="Theme.Sherlock.Light.DarkActionBar">
</resources>
Activity
public class AbstractActivity extends SherlockActivity {
...
public BaseActivity(boolean hasMenuItemInActionBar) {
super();
this.hasMenuItemInActionBar = hasMenuItemInActionBar;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (this.getSupportActionBar() != null) {
this.getSupportActionBar().setDisplayHomeAsUpEnabled(false);
this.getSupportActionBar().setDisplayShowHomeEnabled(false);
this.getSupportActionBar().setDisplayUseLogoEnabled(false);
this.getSupportActionBar().setDisplayShowCustomEnabled(true);
this.getSupportActionBar().setCustomView(R.layout.actionbar_custom);
setTitle(this.getTitle());
}
}
...
}
Using appcompat
Manifest
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
</resources>
Activity
public class AbstractActivity extends ActionBarActivity{
...
public BaseActivity(boolean hasMenuItemInActionBar) {
super();
this.hasMenuItemInActionBar = hasMenuItemInActionBar;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (this.getSupportActionBar() != null) {
this.getSupportActionBar().setDisplayHomeAsUpEnabled(false);
this.getSupportActionBar().setDisplayShowHomeEnabled(false);
this.getSupportActionBar().setDisplayUseLogoEnabled(false);
this.getSupportActionBar().setDisplayShowCustomEnabled(true);
this.getSupportActionBar().setCustomView(R.layout.actionbar_custom);
setTitle(this.getTitle());
}
}
...
}
Android: Spinner with hint text and "setError" like functionality
Adapter:
public class GenderAdapter extends BaseAdapter {
private Context context;
private String[] genderList;
public GenderAdapter(Context context) {
this.context = context;
this.genderList = new String[3];
this.genderList[0] = context.getString(R.string.gender); // Hint text
this.genderList[1] = context.getString(R.string.male);
this.genderList[2] = context.getString(R.string.female);
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.drop_down_row_light_gray, null);
}
TextView text = (TextView) convertView.findViewById(R.id.text);
text.setText(getItem(position));
Resources resources = context.getResources();
text.setTextColor(resources.getColor(position == 0 ? R.color.gray : R.color.dark_gray)); // If it is the hint text (position == 0) set the textcolor to be a lighter color
return convertView;
}
@Override
public int getCount() {
return genderList.length;
}
@Override
public String getItem(int position) {
return genderList[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.closed_row_light_gray, null);
}
TextView text = (TextView) convertView.findViewById(R.id.text);
text.setText(getItem(position));
Resources resources = context.getResources();
text.setTextColor(resources.getColor(position == 0 ? R.color.gray : R.color.dark_gray)); // If it is the hint text (position == 0) set the textcolor to be a lighter color
return convertView;
}
}
drop_down_row_light_gray:<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
style="@style/Base.TextAppearance.AppCompat.Medium"
android:background="@color/light_gray"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="48dp"
android:paddingLeft="8dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:ellipsize="end"
android:textColor="@color/dark_gray"
android:gravity="center"/>
closed_row_light_gray:<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
style="@style/Base.TextAppearance.AppCompat.Medium"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="48dp"
android:paddingLeft="8dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:textColor="@color/dark_gray"
android:gravity="center"/>
Add "setError" to the spinner :private void setSubmitButtonOnClickListener() {
submitButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isFormValid()) {
...
} else {
if (isAgeEmpty()) {
TextView textView = (TextView) ageSpinner.getSelectedView().findViewById(R.id.text); // "text" is the layout id of the TextView that displays the text
textView.setError(getString(R.string.age_is_required));
}
...
}
}
});
}
Notes:
1) In my experience, when I used 9 patch as the spinne's background, the spinner's text dissapeared. It does not happen if I use a "normal" drawable or background color.
2) The "arrow thingy" to the right side of a spinner is actually a background (a 9 patch png). That being said, if you change the spinne background the arrow will dissapear.ng>
Android: White screen when coming back from activity B to activiy A
In the theme of the application or activity's theme add:
<style name="AppTheme" parent="@style/Theme.AppCompat">
// ...
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
<style name="AppTheme" parent="@style/Theme.AppCompat">
// ...
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
jueves, 17 de julio de 2014
Android: Easy share
Uri uri = Uri.fromFile(new File(path));
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_TEXT, "text");
shareIntent.putExtra(Intent.EXTRA_TITLE, "title");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "subject");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); * startActivity(Intent.createChooser(shareIntent, "Share via"));
Note: This can be used with facebook if the application is installed.
* If you leave out the flag, when returning to your app (from homescreen, from recents etc.), you would see the Activity of the share target (messaging/mailing/IM app) instead of yours.
Android: Update ADT to 23
1) Go to Help --> About Eclipse SDK --> Installation Details
2) Select from the list the following plugins:
- Android DDMS
- Android Development Tools
- Android Hierarchy Viewer
- Android Native Development Tools
- Android Traceview
- Tracer for OpenGL ES
Click uninstall and follow the steps
4) Go to Help > Install New Software > http://dl-ssl.google.com/android/eclipse/
5) Select all plugins, and follow the steps and you are done.
2) Select from the list the following plugins:
- Android DDMS
- Android Development Tools
- Android Hierarchy Viewer
- Android Native Development Tools
- Android Traceview
- Tracer for OpenGL ES
Click uninstall and follow the steps
4) Go to Help > Install New Software > http://dl-ssl.google.com/android/eclipse/
5) Select all plugins, and follow the steps and you are done.
viernes, 4 de julio de 2014
Android: Hide keyboard
1) Hide keyboard
private void hideKeyboard() {
EditText calibationEditText = (EditText) findViewById(R.id.calibration);
InputMethodManager imm = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(calibationEditText.getWindowToken(), 0);
calibationEditText.clearFocus();
}
2) I created a dialog with an EditText when I close the dialog the keyboard doesn't disappear, it only changed from input type number to normal.
AndroidManifest.xml
<activity
android:name="ar.com.fennoma.digipad.activities.Activity"
android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysHidden" >
</activity>
Activity is the activity that creates the dialog.
private void hideKeyboard() {
EditText calibationEditText = (EditText) findViewById(R.id.calibration);
InputMethodManager imm = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(calibationEditText.getWindowToken(), 0);
calibationEditText.clearFocus();
}
2) I created a dialog with an EditText when I close the dialog the keyboard doesn't disappear, it only changed from input type number to normal.
AndroidManifest.xml
<activity
android:name="ar.com.fennoma.digipad.activities.Activity"
android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysHidden" >
</activity>
Activity is the activity that creates the dialog.
Android: JNI
Compiling
To be able to compile JNI code you need to create a make file. You can fin examples of working make files in the samples here. I named the Vuforia Android samples since it was because of this library that I had to work with JNI :P
In windows you just have to type the following the commands promt:
For example:
You can find the Android NDK here. You can find the oficial documentation about JNI here.
Loading libs
The compiled library needs to be placed inside "/libs" inside, most likely, the folder named "armeabi-v7a".
For example, to load the library named "libdetection_based_tracker.so" somewhere in your code you have to call the following method: "System.loadLibrary("detection_based_tracker");".
Create an object
Example: Instantiate a Float object
2) Get the constructor method.
<init> indicates its a constructor.
(F)V defines the constructor arguments (the characters inside the parentheses) and the return type (just after the parentheses). In this case the arguments is just a single float (F) and the return type is void (V). You can check all type signatures here.
3) Create a java object given the class (floatClass), the constructor (floatConstructor) and the arguments of the constructor is 5.0.
Calling methods from Android methods with JNI
To be able to compile JNI code you need to create a make file. You can fin examples of working make files in the samples here. I named the Vuforia Android samples since it was because of this library that I had to work with JNI :P
In windows you just have to type the following the commands promt:
cd <path_to_jni_files>
<path_to_android_ndk>\ndk-build
For example:
cd C:\Users\dev\Desktop\Repositories\MyProject\jni
C:\android-ndk-r9c\ndk-build
You can find the Android NDK here. You can find the oficial documentation about JNI here.
Loading libs
The compiled library needs to be placed inside "/libs" inside, most likely, the folder named "armeabi-v7a".
For example, to load the library named "libdetection_based_tracker.so" somewhere in your code you have to call the following method: "System.loadLibrary("detection_based_tracker");".
Create an object
Example: Instantiate a Float object
jclass floatClass = env->FindClass("java/lang/Float"); // 1
jmethodID floatConstructor = env->GetMethodID(floatClass, "<init>", "(F)V"); // 2
jobject float object = env->NewObject(floatClass, floatConstructor, 5.0); // 3
1) We first need to find the class will be working on, in this case, the float class. env is the environment pointer is of type (JNIEnv).2) Get the constructor method.
<init> indicates its a constructor.
(F)V defines the constructor arguments (the characters inside the parentheses) and the return type (just after the parentheses). In this case the arguments is just a single float (F) and the return type is void (V). You can check all type signatures here.
3) Create a java object given the class (floatClass), the constructor (floatConstructor) and the arguments of the constructor is 5.0.
Calling methods from Android methods with JNI
jclass activityClass = env->GetObjectClass(obj);
jmethodID targetDetectedMethodID = env->GetMethodID(activityClass, "targetDetected", "([Ljava/lang/Object;)V");
if (targetDetectedMethodID == 0) {
LOG("Function targetDetected() not found.");
return;
}
env->CallVoidMethod(obj, targetDetectedMethodID, arguments); //1
1) Arguments can be any objects or a var_list
miércoles, 2 de julio de 2014
Android: Obtain image size from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(resources, resourceId, options);
// options.outHeight
// options.outWidth
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(resources, resourceId, options);
// options.outHeight
// options.outWidth
Android: Multiple option share dialog
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, "text");
shareIntent.putExtra(Intent.EXTRA_TITLE, "title");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "subject");
startActivity(Intent.createChooser(shareIntent, "Share via"));
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, "text");
shareIntent.putExtra(Intent.EXTRA_TITLE, "title");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "subject");
startActivity(Intent.createChooser(shareIntent, "Share via"));
Suscribirse a:
Entradas (Atom)