ObjectAnimatorでTextViewの内容を書き換える
ObjectAnimatorおもろいなー setNumber(int)を持つNumberTextViewというクラスを作り
public class NumberTextView extends AppCompatTextView { public NumberTextView(Context context) { super(context); } public NumberTextView(Context context, AttributeSet attrs) { super(context, attrs); } public NumberTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setNumber(int number) { setText(String.valueOf(number)); } }
ObjectAnimatorでエイッとすると
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(binding.numberTextView, "number", 0, 10000); objectAnimator.setDuration(10 * 1000); objectAnimator.setInterpolator(new LinearInterpolator()); objectAnimator.start();
数値がテキストとして表示される
単にリフレクション使って値を設定しているだけなのかなー。
ProgressBarの値をアニメーションで変更する
↑こういうことやりたいんだけど、ProgressBar#setProgress(:int)
だとアニメーションしてくれない。
そうだ、ObjectAnimatorを使ってアニメーションを実現しよう。
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".activity.MainActivity" > <LinearLayout android:orientation="vertical" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent"> <ProgressBar style="?android:attr/progressBarStyleHorizontal" android:id="@+id/progress_bar" android:layout_margin="16dp" android:layout_width="match_parent" android:layout_height="wrap_content"/> <Button android:id="@+id/update_progress_button" android:text="Update progress" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </layout>
public class MainActivity extends AppCompatActivity { ActivityMainBinding binding; ObjectAnimator objectAnimator; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.updateProgressButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int progress = (int) (Math.random() * 100); setProgressWithAnimation(progress); } }); } private void setProgressWithAnimation(int progress) { int[] values = {binding.progressBar.getProgress(), progress}; if (objectAnimator == null) { objectAnimator = ObjectAnimator.ofInt(binding.progressBar, "progress", values); } else { objectAnimator.cancel(); objectAnimator.setIntValues(values); } objectAnimator.setDuration(1000); objectAnimator.setInterpolator(new DecelerateInterpolator(2.0f)); objectAnimator.start(); } }
Activityに書いちゃうとアレなんでカスタムViewでやるとスッキリしそうでよさそう。
アニメーションしている最中はそのときのProgressの値になってしまうので、getProgress()
を使いたいケースではこれは使えない。
Androidエミュレータにテキストをペーストすることができない時代がありました
Androidエミュレータは母艦とクリップボードの共有がされないので、パスワードなどの複雑なテキストを毎回手打ちしなくてはならなくて面倒でした。
そこで、簡単にコピペできるような関数を作りました。
function paste_in_android() { e=$(pbpaste | sed -e "s/ /\\\\ /g" | sed -e "s/'/\\\\'/g" | sed -e 's/"/\\"/g') adb shell input text "$e" }
クリップボードに入っているテキストをadb経由で入力します。
input text
を使っているためマルチバイト文字を渡すことはできなく、さらにIMEの状態によって入力のされ方が変わります。 adbを経由するので、エミュレータだけではなく実機でも使うことができます。面倒なURLの入力にも使えるんじゃないでしょうか。
うまくうごかなかったら、エスケープすべき文字があるんだと思います。sed
でエスケープ処理を追加してください。
私はターミナルで入力するのすら面倒なのでAlfred workflowにしておきました。(リポジトリのgifアニを見ればどういう風に使うのか一発で分かると思います。)
github.com
べんり〜
という時代もありました。 現代のAndroidエミュレータではいい感じにしてくれるので、EditTextなどを長押しすればペーストすることができます。
テキストボックス長押しとかでコンテキストメニューだしてペーストできない?
— Sosuke Masui ⋈ (@esmasui) August 28, 2019
コマンドラインから特定のクラスのみテストする
次のコマンドで実現できる
./gradlew connectedAndroidTest -Pcom.android.tools.instrumentationTestRunnerArgs=class=com.example.Util
com.android.tools.instrumentationTestRunnerArgs
にはいろんなオプションが指定でき、どんなオプションがあるかは次のURLから見ることができる
AndroidJUnitRunner | Android Developers
複数の引数を指定する場合はカンマで区切る
./gradlew connectedAndroidTest -Pcom.android.tools.instrumentationTestRunnerArgs=class=com.example.Util,size=medium
キーが重複するハッシュをマージする
2つのハッシュをマージするときにキーが重複するとレシーバを優先されてしまう
$ pry [1] pry(main)> h1 = {a: [1, 2, 3], b: [1, 2, 3]} => {:a=>[1, 2, 3], :b=>[1, 2, 3]} [2] pry(main)> h2 = {a: [10], c: [10,11]} => {:a=>[10], :c=>[10, 11]} [3] pry(main)> h1.merge(h2) => {:a=>[10], :b=>[1, 2, 3], :c=>[10, 11]}
Hash#mergeはブロックを受け取ることができて、キーが重複した時の挙動を指定することができる
$ pry [1] pry(main)> h1 = {a: [1, 2, 3], b: [1, 2, 3]} => {:a=>[1, 2, 3], :b=>[1, 2, 3]} [2] pry(main)> h2 = {a: [10], c: [10,11]} => {:a=>[10], :c=>[10, 11]} [3] pry(main)> h1.merge(h2) { |key, h1v, h2v| h1v + h2v } => {:a=>[1, 2, 3, 10], :b=>[1, 2, 3], :c=>[10, 11]}
Array#shuffleで同じ結果を得る
shuffleの引数に同じRandomオブジェクトを渡せば何度シャッフルしても同じ結果になる
$ pry [1] pry(main)> Array(1...10).shuffle(random: Random.new(473)) => [6, 4, 9, 5, 8, 3, 2, 1, 7] [2] pry(main)> Array(1...10).shuffle(random: Random.new(473)) => [6, 4, 9, 5, 8, 3, 2, 1, 7] [3] pry(main)> Array(1...10).shuffle(random: Random.new(473)) => [6, 4, 9, 5, 8, 3, 2, 1, 7]
配列の重複を取得する
@tomorrowkey ブログ読んでて気になったんですけど、Arrayは&&をoverloadしてるのでこれで重複要素取れます! https://t.co/dkNFp9fW5Y https://t.co/5vChxCdXdF
— ぎぎにゃん@脱北者 (@giginet) November 7, 2015
たしかに〜
$ pry [1] pry(main)> Array(1..10) && Array(5..6) => [5, 6]
超簡単だった。
重複を除外するならuniq使えばいいけど、重複を取得するのはメソッドがなかった。
こんな感じに書けば重複した値が取得できる
$ pry [1] pry(main)> require 'active_support/all' => true [2] pry(main)> (Array(1..10) + Array(5..6)).group_by{|i| i}.reject{|k, v| v.one?}.keys => [5, 6]