目的
特定のアプリで生きているActivityの一覧を確認する。前提
・PCでadbコマンドが実行できる状態・確認したいアプリが起動している端末のUSBデバッグが有効な状態
・PCに端末が接続されている
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="bottom"
android:background="@color/white"
app:elevation="8dp"
app:labelVisibilityMode="labeled"
app:itemIconTint="@color/slector_bottom_navigation"
app:itemTextColor="@color/slector_bottom_navigation"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_navigation" />
heightの56dpは、https://material.io/design/components/bottom-navigation.html#specs を参考
val menuView = view.getChildAt(0) as BottomNavigationMenuView
try {
val shiftingMode = menuView::class.java.getDeclaredField("mShiftingMode")
shiftingMode.isAccessible = true
shiftingMode.setBoolean(menuView, false)
shiftingMode.isAccessible = false
for (i in 0 until menuView.childCount) {
val bottomNavigationItemView = menuView.getChildAt(i) as BottomNavigationItemView
bottomNavigationItemView.setShiftingMode(false)
bottomNavigationItemView.setChecked(false)
}
} catch (e: NoSuchFieldException) {
Log.d(TAG, "ERROR", e)
} catch (e: IllegalAccessException) {
Log.d(TAG, "ERROR", e)
}
| returnがレシーバ | returnが任意 | |
|---|---|---|
| レシーバの 拡張関数 |
apply | with run |
| 任意の型の 拡張関数 |
also | let |
repositories {
maven {
url 'https://download.01.org/crosswalk/releases/crosswalk/android/maven2'
}
}
android {
// ...
}
dependencies {
// ...
compile "org.xwalk:xwalk_core_library:17.46.448.10"
// ...
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fragmentTransaction { ft -> ft.add(R.id.fragment_container, MainFragment()) }
}
fun AppCompatActivity.fragmentTransaction(transaction: (ft: FragmentTransaction) -> Unit) {
val ft = supportFragmentManager.beginTransaction()
transaction(ft)
ft.commit()
}
}
ViewGroup#setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);を設定して、ピッカーにフォーカスがいかないように設定することによって、ピッカーをタップしてもキーボードが表示されなくなる。
// 矢印の色変更 final Drawable upArrow = getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha); upArrow.setColorFilter(getResources().getColor(R.color.drawer_arrows), PorterDuff.Mode.SRC_ATOP); getSupportActionBar().setHomeAsUpIndicator(upArrow);
public class AutoHideKeyboardEditText extends EditText {
protected boolean mHideKeyboardEnable = true;
public AutoHideKeyboardEditText(Context context) {
super(context);
}
public AutoHideKeyboardEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setHideKeyboardEnable(final boolean enabled) {
mHideKeyboardEnable = enabled;
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (mHideKeyboardEnable && !focused) {
// ソフトキーボードを非表示にする
final InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
public static void openBrowser(final Context context, final String url) {
try {
// 標準ブラウザ起動
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setClassName("com.android.browser", "com.android.browser.BrowserActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
try {
// chrome起動
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setClassName("com.android.chrome", "com.google.android.apps.chrome.Main");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (ActivityNotFoundException e2) {
// 暗黙的intentでブラウザ起動
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}
}
public boolean isInstalled(final Context context) {
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("scheme:"));
final List resolveInfos = context.getApplicationContext()
.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
return (resolveInfos != null && !resolveInfos.isEmpty());
}
[Desktop Entry] Encoding=UTF-8 Version=1.0 Type=Application Name=Android Studio Icon=/home/ysakaguchi/Android/android-studio/bin/studio.ico Path=/home/ysakaguchi/Android/android-studio/bin Exec=/home/ysakaguchi/Android/android-studio/bin/studio.sh
repositories {
…
mavenCentral()
…
}
dependencies {
…
compile 'com.facebook.android:facebook-android-sdk:3.23.1'
…
}
final int MAX_TEXT_LENGTH = 10;
final EditText editText = (EditText) findViewById(R.id.edit_text);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (unfixInput(s)) {
return;
}
final String str = s.toString();
final String adjustedText = adjustText(str);
if (!str.equals(adjustedText)) {
editText.setText(adjustedText);
editText.setSelection(editText.getText().length());
Toast.makeText(getApplicationContext(), String.format("最大%d文字です", MAX_TEXT_LENGTH), Toast.LENGTH_SHORT).show();
return;
}
// TODO 内容保存処理
}
/**
* 入力確定前の文字があるときtrue
*/
private boolean unfixInput(final Editable s) {
Object[] spanned = s.getSpans(0, s.length(), Object.class);
if (spanned != null) {
for (Object obj : spanned) {
if ((s.getSpanFlags(obj) & Spanned.SPAN_COMPOSING) == Spanned.SPAN_COMPOSING) {
return true;
}
}
}
return false;
}
/**
* 文字列の調整
*/
private String adjustText(final String str) {
if (MAX_TEXT_LENGTH < str.codePointCount(0, str.length())) { // 文字数は、コードポイントで比較
return adjustText(str.substring(0, (str.length() - 1)));
}
return str;
}
});
android:maxLength="10"と設定しても、 文字数のカウントがサロゲートの文字が配慮されておらず、絵文字など、文字コードがサロゲートの場合、1文字で2文字と認識されてしまいます。