2014年9月12日金曜日

Androidで角毎に丸みの異なる角丸ボタンを作る

AndroidのShapeDrawableで、
<corners android:radius="5dp" />
みたいな指定をすると四隅すべて角丸になりますが、これはbottomLeftRadiusのように各角毎に指定できます。
サンプルは以下の通り。


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- unpressed -->
<itemandroid:state_pressed="false">
 <shape android:shape="rectangle">
 <solid android:color="#3366ff" />
 <corners 
 android:bottomLeftRadius="20dp" 
 android:bottomRightRadius="20dp"
 android:topLeftRadius="20dp" 
 android:topRightRadius="0dp" />
 </shape>
</item>
<itemandroid:state_pressed="true">
 <shape android:shape="rectangle">
 <solid android:color="#6699ff" />
 <corners 
 android:bottomLeftRadius="10dp" 
 android:bottomRightRadius="10dp"
 android:topLeftRadius="10dp" 
 android:topRightRadius="0dp" />
 </shape>
</item>
</selector>


2014年8月12日火曜日

ウィジェットが置かれたのがロックスクリーンかホームスクリーンかを判断する

ウィジェットが置かれたのがロックスクリーンかホームスクリーンかを判断するには、以下を自前のAppWidgetProviderクラスのonUpdateから呼び出せばOK

 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
 public boolean isPlacedOnLockscreen(Context context, int appWidgetId ){
  if( Build.VERSION.SDK_INT < 17 ){
   return false;
  }
  AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
  Bundle myOptions = appWidgetManager.getAppWidgetOptions(appWidgetId);
  int category = myOptions.getInt(
    AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1);
  return category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD; 
 }


ただしonDeletedからは読み出せないもよう。
回避策としては「データのクリア」を実行されないことを期待してPreferenceにappWidgetIdごとにどちらに置かれたら記憶させておくとかしますかね。

2014年8月5日火曜日

TextViewでgravity="center"にしても真ん中に寄らないで下にずれる

AndroidのTextViewで高さと文字サイズを指定したとき、TextViewに対して文字が大きすぎると、gravity="center"やpadding="0dp"を指定していても文字が下に寄る(つまり上部に余白ができる)ことがある。
例えば以下のようなレイアウトを表示させると
<FrameLayout 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="300dp"
        android:layout_height="40dp"
        android:layout_gravity="center"
        android:background="#dddddd"
        android:gravity="center"
        android:padding="0dp"
        android:text="あいうえおjkl"
        android:textAlignment="gravity"
        android:textSize="40dp" />
</FrameLayout>
こうなる↓

解決策はandroid:includeFontPadding="false"を追加すること。
追加すると、以下のように上部の余白がなくなる





2014年5月2日金曜日

MediaScannerConnection.scanFileを同期処理させる

MediaScannerConnection.scanFileでファイルをスキャンさせてその完了を待つコードを考えてみた。が、どんな状況でも動くようにさせるのは難しそうだ。
以下のようなコードはうまくいきそうだが、実際には状況によってはうまくいかない。

  final Object lock = new Object();
  synchronized (lock) {
   Log.d(TAG, "ScanFile Start");
   MediaScannerConnection.scanFile(context, new String[] { filePath },
     null, new OnScanCompletedListener() {

      @Override
      public void onScanCompleted(String path, Uri uri) {
       Log.d(TAG, "onScanCompleted");
       synchronized (lock) {
        lock.notify();
       }
      }
     });
   try {
    Log.d(TAG, "lock start");
    lock.wait();
    Log.d(TAG, "unlocked");
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
その状況とは、このコードがUIスレッドで動いている場合。
おそらくMediaScannerServiceへconnectしてonMediaScannerConnectedを待つあたりでUIスレッドが動いていないと駄目なんだろうなーと。

というわけで、回避策としては非同期にできるところまでさかのぼって、別スレッドで動かすしかなさそう。
それが嫌なら、MediaScannerConnection インスタンスを作って(事前にサービスへの接続をしておいて)scanFileすればいけるんじゃないですかね(試してません)。

2014年4月21日月曜日

AcitivtyのonCreateでactivity has been destroyed というエラーで落ちるときの原因

以下のようなコードはactivity has been destroyed と言われ落ちます。
環境は Nexus5 / KitKat


public class MyActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
          FragmentManager fragMgr = getSupportFragmentManager();

          FirstFragment list = new FirstFragment();
          fragMgr.beginTransaction().add(android.R.id.content, list).commit();
          super.onCreate(savedInstanceState);
    }

}
解決策はsuper.onCreateを最初にもってくるだけ。はまったー。
public class MyActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          FragmentManager fragMgr = getSupportFragmentManager();

          FirstFragment list = new FirstFragment();
          fragMgr.beginTransaction().add(android.R.id.content, list).commit();
    }

}

2014年2月26日水曜日

androidのListViewでスクロールする時、最初だけカクつく(ラグる)

AndroidのListViewでスクロールする時、初回だけカクついてそれ以降はスムーズになる場合がある。例えばTwiccaのスクロールはこうなる。

このラグを無くすにはAndroidManifestのapplicateionタグに
        android:hardwareAccelerated="true"
を足す。
これだけ。お試しあれ。

2014年2月5日水曜日

Android + NDK debug で No source file named *****.c の原因

AndroidのNDKでnativeのコードをデバッグしようとすると
ブレークポイントを貼ったソースファイル名で

 No source file named *****.c

というようなエラーが出た。

原因は簡単で、先に

static {
System.loadLibrary("mylibrary");
}

のように共有ライブラリーをロードしなければいけないのでした。