カテゴリー
Android Java

Custom Button in Android

// activity

public class MainActivity extends AppCompatActivity {

    Button button1;

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getSupportActionBar().hide();

        RelativeLayout rootLinearLayout = new RelativeLayout(this);
        rootLinearLayout.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
        rootLinearLayout.setBackgroundColor(Color.CYAN);
        setContentView(rootLinearLayout);


        OvalShape ovalShape = new OvalShape();
        ShapeDrawable shapeDrawable = new ShapeDrawable(ovalShape);
        shapeDrawable.getPaint().setColor(Color.GRAY); // Change this to your desired color.

        button1 = new Button(this);
        button1.setText("Task1");
        int button1Id = View.generateViewId();
        button1.setId(button1Id);

        int size = 200; // Change this to your desired size.
        RelativeLayout.LayoutParams buttonLP = new RelativeLayout.LayoutParams(size, size);
        buttonLP.addRule(RelativeLayout.CENTER_IN_PARENT);

        RelativeLayout.LayoutParams buttonLP1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        buttonLP1.addRule(RelativeLayout.CENTER_IN_PARENT);
        button1.setLayoutParams(buttonLP);
        button1.setOnClickListener(new OnButtonClicked());

        button1.setOnTouchListener(new OnButtonTouched(Color.GRAY, Color.BLUE));

        button1.setBackground(shapeDrawable);
        rootLinearLayout.addView(button1);
    }
}

// custom onTouchListener

public class OnButtonTouched implements View.OnTouchListener {
    private final int normalColor;
    private final int pressedColor;

    private static final String TAG = "ButtonClicked";

    public OnButtonTouched(int normalColor, int pressedColor) {
        this.normalColor = normalColor;
        this.pressedColor = pressedColor;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.d(TAG, "in touched");
        if (!(v.getBackground() instanceof ShapeDrawable)) {
            return false; // Return false if the background is not of the expected type
        }

        ShapeDrawable shapeDrawable = (ShapeDrawable) v.getBackground();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // Button pressed: change color
                shapeDrawable.getPaint().setColor(pressedColor);
                v.invalidate(); // Force the button to be redrawn
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // Button released or touch cancelled: revert to original color
                shapeDrawable.getPaint().setColor(normalColor);
                v.invalidate(); // Force the button to be redrawn
                break;
        }
        return false; // Return false to indicate not to consume touch events, let them propagate so the onClick events will fire.
    }
}
カテゴリー
Android Java

Android 101 (初歩)

Trivial thing as adding a square can be intimidating when you start out coding…

So, here are some of the steps to guide you through how to grasp the very basic concepts in Android development.

When you create new project in Android Studio, it automatically generates a below code for you.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); // 1
    }
}

The code “1” basically says, “to set the activity_main.xml as the root layout”. In Android, you must have a root layout to contain other child elements such as layouts, views, buttons, etc.

There are other types of layouts such as RelativeLayout, etc. You can learn more in Google’s official document.

In a real-world scenario, you will often be required to write your program in “code”, so let’s see how we can replace this line “programmatically”

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 2. root LinearLayout
        LinearLayout rootLinearLayout = new LinearLayout(this);
        rootLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        rootLinearLayout.setOrientation(LinearLayout.VERTICAL);
        setContentView(rootLinearLayout);
    }
}

in code “2”, we are creating a LinearLayout object and setting it as the contentView. You can think of it as the “root container for everything else” in that particular screen.

LinearLayout needs a layoutParams, and it is set to “MATCH_PARENT”, so it stretches to fit the entirety of the device screen.

LinearLayout automatically lines up any child element vertically or horizontally. Here, we are setting it to “VERTICAL”

When you build the project, you get this.

It looks pretty,,, BLANK!, but congratulations, you have just created a rootLinearLayout from scratch, programmatically.

Next, let’s add color to this rootLayout. It is easy as this.

rootLinearLayout.setBackgroundColor(Color.CYAN);

In case you want to change the App title, you can change it in app -> manifests -> AndroidManifests.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name" // 3
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SimpleSquareExample"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>

The code “3” is the line you want to look at. It says “@string/app_name”. It means a variable “app_name” is kept in a string file for the app name. You can find the string file at app -> res -> values -> strings.xml

<resources>
    <string name="app_name">Simple Square Example</string>
</resources>

In case you don’t want the app name to be displayed at all, you can set it in the onCreate() method (4).

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide(); // 4
        // root LinearLayout
        LinearLayout rootLinearLayout = new LinearLayout(this);
        rootLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        rootLinearLayout.setOrientation(LinearLayout.VERTICAL);
        rootLinearLayout.setBackgroundColor(Color.CYAN);
        setContentView(rootLinearLayout);
    }
}

Let’s now add a child element to the rootLinearLayout.

Follow 5, 6 and 7 in the code below.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        // root LinearLayout
        LinearLayout rootLinearLayout = new LinearLayout(this);
        rootLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        rootLinearLayout.setOrientation(LinearLayout.VERTICAL);
        rootLinearLayout.setBackgroundColor(Color.CYAN);
        setContentView(rootLinearLayout);

        // 5. creating a layout params
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);

        // 6. creating an element, color it red and set the weight
        RelativeLayout elementOne = new RelativeLayout(this);
        elementOne.setBackgroundColor(Color.RED);
        params.weight = 1;
        elementOne.setLayoutParams(params);

        // 7. add child element to the rootLinearLayout
        rootLinearLayout.addView(elementOne);

    }
}

I’m sure you are wondering, what is “weight”…?

It will be clear once you add another element to the rootLinearElement. Add the below code “8” in your onCreate() method.

// 8. creating another element, and adding to the rootLinearLayout
RelativeLayout elementTwo = new RelativeLayout(this);
elementTwo.setBackgroundColor(Color.BLUE);
elementTwo.setLayoutParams(params);

rootLinearLayout.addView(elementTwo);

Do you get the point? LinearLayout lets you align child elements in vertical or horizontal fashion. But, what if you want to change the ratio of the element size, like make the blue square bigger than the red?

It is easy. You create another layout params and set the weight as you like. Your entire code will look something like this. The code 9 and 10 are where you want to look at.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        // root LinearLayout
        LinearLayout rootLinearLayout = new LinearLayout(this);
        rootLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        rootLinearLayout.setOrientation(LinearLayout.VERTICAL);
        rootLinearLayout.setBackgroundColor(Color.CYAN);
        setContentView(rootLinearLayout);

        // creating a layout params
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);

        // creating an element
        RelativeLayout elementOne = new RelativeLayout(this);
        elementOne.setBackgroundColor(Color.RED);
        params.weight = 1;
        elementOne.setLayoutParams(params);

        // add child element to the rootLinearLayout
        rootLinearLayout.addView(elementOne);

        // 9. create another layout params
        LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        params2.weight = 2;

        // creating another element, and adding to the rootLinearLayout
        RelativeLayout elementTwo = new RelativeLayout(this);
        elementTwo.setBackgroundColor(Color.BLUE);
        // 10. set params2 to the element
        elementTwo.setLayoutParams(params2);

        rootLinearLayout.addView(elementTwo);

    }
}

“weight” can be any floating point value.

Next, let’s make the corner of the square rounded. Use a class called GradientDrawable.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        // root LinearLayout
        LinearLayout rootLinearLayout = new LinearLayout(this);
        rootLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        rootLinearLayout.setOrientation(LinearLayout.VERTICAL);
        rootLinearLayout.setBackgroundColor(Color.CYAN);
        setContentView(rootLinearLayout);

        // creating a layout params
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);

        // creating an element
        RelativeLayout elementOne = new RelativeLayout(this);
        elementOne.setBackgroundColor(Color.RED);
        params.weight = 1;
        elementOne.setLayoutParams(params);

        // add child element to the rootLinearLayout
        rootLinearLayout.addView(elementOne);

        // create another layout params
        LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        params2.weight = 2;

        // 11. for rounded corner
        GradientDrawable gd = new GradientDrawable();
        gd.setColor(Color.YELLOW);
        gd.setCornerRadius(200);

        // creating another element, and adding to the rootLinearLayout
        RelativeLayout elementTwo = new RelativeLayout(this);
        elementTwo.setBackgroundColor(Color.BLUE);
        // 12. set gd as the background. Noticed the element's background color is no longer blue, but yellow?
        elementTwo.setBackground(gd);
        // set params2 to the element
        elementTwo.setLayoutParams(params2);

        rootLinearLayout.addView(elementTwo);
    }
}

You can create complex layout just by using LinearLayout or RelativeLayout, and add child elements to it, however ways you want. Follow steps 13 – 19 to see how it works.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        // root LinearLayout
        LinearLayout rootLinearLayout = new LinearLayout(this);
        rootLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        rootLinearLayout.setOrientation(LinearLayout.VERTICAL);
        rootLinearLayout.setBackgroundColor(Color.CYAN);
        setContentView(rootLinearLayout);

        // creating a layout params
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);

        // creating an element
        // 13. change the layout type to LinearLayout
        LinearLayout elementOne = new LinearLayout(this);
        // 14. set orientation to HORIZONTAL
        elementOne.setOrientation(LinearLayout.HORIZONTAL);
        elementOne.setBackgroundColor(Color.RED);
        params.weight = 1;
        elementOne.setLayoutParams(params);

        // 15. creating childElements
        LinearLayout childElementOne = new LinearLayout(this);
        childElementOne.setBackgroundColor(Color.GREEN);
        // 16.  create a layout params
        LinearLayout.LayoutParams childLP = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
        childLP.weight = 1;
        childElementOne.setLayoutParams(childLP);

        // 17. adding childElement to elementOne
        elementOne.addView(childElementOne);

        // 18. creating another child element
        LinearLayout childElementTwo = new LinearLayout(this);
        childElementTwo.setBackgroundColor(Color.BLUE);
        childElementTwo.setLayoutParams(childLP);

        // 19. adding it to the parent element
        elementOne.addView(childElementTwo);

        // add child element to the rootLinearLayout
        rootLinearLayout.addView(elementOne);

        // create another layout params
        LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        params2.weight = 2;

        // for rounded corner
        GradientDrawable gd = new GradientDrawable();
        gd.setColor(Color.YELLOW);
        gd.setCornerRadius(200);

        // creating another element, and adding to the rootLinearLayout
        RelativeLayout elementTwo = new RelativeLayout(this);
        elementTwo.setBackgroundColor(Color.BLUE);
        elementTwo.setBackground(gd);
        // set params2 to the element
        elementTwo.setLayoutParams(params2);

        rootLinearLayout.addView(elementTwo);

    }
}

Lastly, you can get crazier elements inside RelativeLayout. Follow steps 20 – 30.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        // root LinearLayout
        LinearLayout rootLinearLayout = new LinearLayout(this);
        rootLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        rootLinearLayout.setOrientation(LinearLayout.VERTICAL);
        rootLinearLayout.setBackgroundColor(Color.CYAN);
        setContentView(rootLinearLayout);

        // creating a layout params
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);

        // creating an element
        // change the layout type to LinearLayout
        LinearLayout elementOne = new LinearLayout(this);
        // set orientation to HORIZONTAL
        elementOne.setOrientation(LinearLayout.HORIZONTAL);
        elementOne.setBackgroundColor(Color.RED);
        params.weight = 1;
        elementOne.setLayoutParams(params);

        // creating childElements
        LinearLayout childElementOne = new LinearLayout(this);
        childElementOne.setBackgroundColor(Color.GREEN);
        // create a layout params
        LinearLayout.LayoutParams childLP = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
        childLP.weight = 1;
        childElementOne.setLayoutParams(childLP);

        elementOne.addView(childElementOne);

        LinearLayout childElementTwo = new LinearLayout(this);
        childElementTwo.setBackgroundColor(Color.BLUE);
        childElementTwo.setLayoutParams(childLP);

        elementOne.addView(childElementTwo);

        // add child element to the rootLinearLayout
        rootLinearLayout.addView(elementOne);

        // create another layout params
        LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        params2.weight = 2;

        // for rounded corner
        GradientDrawable gd = new GradientDrawable();
        gd.setColor(Color.YELLOW);
        gd.setCornerRadius(200);

        // creating another element, and adding to the rootLinearLayout
        RelativeLayout elementTwo = new RelativeLayout(this);
        elementTwo.setBackgroundColor(Color.BLUE);
        elementTwo.setBackground(gd);
        // set params2 to the element
        elementTwo.setLayoutParams(params2);

        rootLinearLayout.addView(elementTwo);

        // 20. creating child elements for elementTwo
        RelativeLayout childElementA = new RelativeLayout(this);
        childElementA.setBackgroundColor(Color.RED);
        // 21. new layout params and set width and height to 200 
        RelativeLayout.LayoutParams rlp1 = new RelativeLayout.LayoutParams(200, 200);
        // 22. add rule to make it align to the parent's top
        rlp1.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        childElementA.setLayoutParams(rlp1);
        // 23. generating an ID for the view. View.generateViewId() will automatically generate an ID that does not conflict with other IDs. It is a lot better than you manually managing them.
        childElementA.setId(View.generateViewId());

        // 24. adding it to the elementTwo
        elementTwo.addView(childElementA);

        // 25. creating another child element
        RelativeLayout childElementB = new RelativeLayout(this);
        childElementB.setBackgroundColor(Color.MAGENTA);
        // 26. creating another layout params. This time, set the width and height to 400
        RelativeLayout.LayoutParams rlp2 = new RelativeLayout.LayoutParams(400, 400);
        // 27. adding a rule to make it just below childElementA
        rlp2.addRule(RelativeLayout.BELOW, childElementA.getId());
        // 28. you can even add margins to it!
        rlp2.topMargin = 50;
        // 29. add another rule to make it align to the right of childElementA
        rlp2.addRule(RelativeLayout.RIGHT_OF, childElementA.getId());
        // 30. again, you can add whatever margins to it!
        rlp2.leftMargin = 100;
       
        childElementB.setLayoutParams(rlp2);

        elementTwo.addView(childElementB);
    }
}

Oh, yes. One final tip. In order to get the perfect circle, set the cornerRadius the half size of the shape. Follow, 31 – 33

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        // root LinearLayout
        LinearLayout rootLinearLayout = new LinearLayout(this);
        rootLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        rootLinearLayout.setOrientation(LinearLayout.VERTICAL);
        rootLinearLayout.setBackgroundColor(Color.CYAN);
        setContentView(rootLinearLayout);

        // creating a layout params
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);

        // creating an element
        // change the layout type to LinearLayout
        LinearLayout elementOne = new LinearLayout(this);
        // set orientation to HORIZONTAL
        elementOne.setOrientation(LinearLayout.HORIZONTAL);
        elementOne.setBackgroundColor(Color.RED);
        params.weight = 1;
        elementOne.setLayoutParams(params);

        // creating childElements
        LinearLayout childElementOne = new LinearLayout(this);
        childElementOne.setBackgroundColor(Color.GREEN);
        // create a layout params
        LinearLayout.LayoutParams childLP = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
        childLP.weight = 1;
        childElementOne.setLayoutParams(childLP);

        elementOne.addView(childElementOne);

        LinearLayout childElementTwo = new LinearLayout(this);
        childElementTwo.setBackgroundColor(Color.BLUE);
        childElementTwo.setLayoutParams(childLP);

        elementOne.addView(childElementTwo);

        // add child element to the rootLinearLayout
        rootLinearLayout.addView(elementOne);

        // create another layout params
        LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        params2.weight = 2;

        // for rounded corner
        GradientDrawable gd = new GradientDrawable();
        gd.setColor(Color.YELLOW);
        gd.setCornerRadius(200);

        // creating another element, and adding to the rootLinearLayout
        RelativeLayout elementTwo = new RelativeLayout(this);
        elementTwo.setBackgroundColor(Color.BLUE);
        elementTwo.setBackground(gd);
        // set params2 to the element
        elementTwo.setLayoutParams(params2);

        rootLinearLayout.addView(elementTwo);

        // creating child elements for elementTwo
        RelativeLayout childElementA = new RelativeLayout(this);
        childElementA.setBackgroundColor(Color.RED);
        RelativeLayout.LayoutParams rlp1 = new RelativeLayout.LayoutParams(200, 200);
        rlp1.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        childElementA.setLayoutParams(rlp1);
        childElementA.setId(View.generateViewId());

        elementTwo.addView(childElementA);

        RelativeLayout childElementB = new RelativeLayout(this);
        childElementB.setBackgroundColor(Color.MAGENTA);

        RelativeLayout.LayoutParams rlp2 = new RelativeLayout.LayoutParams(400, 400);

        // 31. create another GradientDrawable
        GradientDrawable gd2 = new GradientDrawable();
        // 32. btw, you can assign any color by using Color.argb method.
        gd2.setColor(Color.argb(255, 252, 186, 3));
        // 33. set cornerRatius to 200 (half of 400)
        gd2.setCornerRadius(200);
        childElementB.setBackground(gd2);

        rlp2.addRule(RelativeLayout.BELOW, childElementA.getId());
        rlp2.addRule(RelativeLayout.RIGHT_OF, childElementA.getId());
        rlp2.leftMargin = 100;
        rlp2.topMargin = 50;
        childElementB.setLayoutParams(rlp2);

        elementTwo.addView(childElementB);
    }
}
カテゴリー
Android Java RxJava

RxJavaを学ぶ(その3)

バックグラウンド・スレッドからメインスレッドにタスクを返したい場合は、subscribe()の前段にobserveOn(AndroidSchedulers.mainThread())を挿入する。これでバックグラウンド・タスクの結果によるUIのアップデートが可能。

下記はCompositeDisposableにdisposeを任せる例も兼ねて書いてみた。

Disposable isCountingDownDisposable = playMidi.isCountingDownSubject.observeOn(AndroidSchedulers.mainThread()).subscribe(value -> {
      if (value) {
        playButton.setImageResource(R.drawable.ic_round_loop_24);
        playButton.setPadding(10,10,10,10);
      } else {
        playButton.setImageResource(R.drawable.ic_play_fill);
        playButton.setPadding(-20,-20,-20,-20);
      }
    });
compositeDisposable.add(isCountingDownDisposable);
カテゴリー
Android Java

カスタムTouch Controlを作ってみた

スクリーン上で指を上下させることで値を増減させられるコントローラーを書いてみました。

private class OnAreaTouched implements View.OnTouchListener {

    double initialY = 0.0;
    double previousY = 0.0;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
      switch(event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          initialY = event.getY();
          break;
        case MotionEvent.ACTION_MOVE:
          double currentY = event.getY();
          // if finger initially went upwards, then changed it's direction to downwards
          if(currentY < initialY && currentY > previousY) {
            initialY = previousY;
          }
          // if finger initially went downwards, then changed it's direction to upwards
          if(currentY > initialY && currentY < previousY) {
            initialY = previousY;
          }
          double diff = (initialY - currentY) / 100;
          Log.d("MyTest", "initial: " + initialY + ", getY(): " + event.getY() + ", diff: " + diff);
          mValue = mValue + diff;
          // upper bound 400, lower bound 20
          mValue = Math.max(Math.min(mValue, 400), 20);
          String mValueString = "" + (int)mValue;
          SpannableString mValueSpanString = new SpannableString(mValueString);
          mValueSpanString.setSpan(new StyleSpan(Typeface.BOLD), 0, mValueSpanString.length(), 0);
          mValueTV.setText(mValueSpanString);
          previousY = event.getY();
          break;
        default:
          break;
      }
      return true;
    }
}
カテゴリー
Android Java

RelativeLayoutでViewをCenterに配置

public class MainActivity extends AppCompatActivity {

  BackgroundService bs;

  Button button1;
  Button button2;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    RelativeLayout rootLayout = new RelativeLayout(this);
    setContentView(rootLayout);

    bs = BackgroundService.getInstance();

    button1 = new Button(this);
    button1.setText("Task1");
    int button1Id = View.generateViewId();
    button1.setId(button1Id);
    RelativeLayout.LayoutParams buttonLP1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    buttonLP1.addRule(RelativeLayout.CENTER_IN_PARENT);
    button1.setLayoutParams(buttonLP1);
    button1.setOnClickListener(new OnButtonClicked());

    rootLayout.addView(button1);

    button2 = new Button(this);
    button2.setText("Task2");
    RelativeLayout.LayoutParams buttonLP2 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    buttonLP2.addRule(RelativeLayout.BELOW, button1Id);
    buttonLP2.addRule(RelativeLayout.CENTER_HORIZONTAL);
    buttonLP2.topMargin = 20;
    button2.setLayoutParams(buttonLP2);

    rootLayout.addView(button2);
  }

  private class OnButtonClicked implements View.OnClickListener {

    @Override
    public void onClick(View v) {
      bs.backgroundTask1();
    }
  }

  private class OnButton2Clicked implements View.OnClickListener {

    @Override
    public void onClick(View view) {
      bs.backgroundTask2();
    }
  }
}
カテゴリー
Android Java

ClassをSingletonにするには

public class BackgroundService {
  
  public static BackgroundService getInstance() { return SingletonHolder.INSTANCE; }
  private static class SingletonHolder { private static final BackgroundService INSTANCE = new BackgroundService(); }
  private BackgroundService() {}

}
カテゴリー
Android Java RxJava

RxJavaを学ぶ(その2)

値を代入すると、Subscriberで何か処理がトリガーされるようなコード

Subject<Integer> intSubject = PublishSubject.create();
intSubject.subscribe(i -> Log.d(TAG, "Logging: " + i));


private class onButtonClicked implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        intSubject.onNext(17);
    }
}

// when the button is clicked, Logs out "Logging: 17"
カテゴリー
Android Java RxJava

RxJavaを学ぶ(その1)

全体像を掴むために、このビデオは分かりやすくていいと思います!

まずは、最小構成

Observable<String> myObservable = Observable.just("Some new string", "Some other String", "Another");
// "s" is a subscribed string, and logging it when received in onNext
myObservable.subscribe(s -> Log.d(TAG, "Logging: " + s));

Observerを設定し、処理を記述することもできる

myObserver = new Observer<String>() {
      @Override
      public void onSubscribe(@NonNull Disposable d) {
        Log.i(TAG, "onSubscribe invoked");
      }

      @Override
      public void onNext(@NonNull String s) {
        Log.i(TAG, "onNext invoked");
        Log.i(TAG, "Logging " + s);
      }

      @Override
      public void onError(@NonNull Throwable e) {
        Log.i(TAG, "onError invoked");
      }

      @Override
      public void onComplete() {
        Log.i(TAG, "onComplete invoked");
      }
};

myObservable.subscribe(myObserver);
カテゴリー
Android Java

ImageButtonのstyling

private ImageButton getCircleImageButton(int size, int resource) {
  ImageButton button = new ImageButton(this);
  GradientDrawable buttonGD = new GradientDrawable();
  buttonGD.setSize(size, size);
  buttonGD.setColor(Constant.appBackgroundColor);
  buttonGD.setCornerRadius(size / 2);
  buttonGD.setStroke(10, Constant.buttonLineColor);
  button.setBackground(buttonGD);

  button.setImageResource(resource);
  button.setScaleType(ImageButton.ScaleType.FIT_CENTER);
  button.setClipToOutline(true);
  return button;
}
カテゴリー
Android Java

res/rawフォルダ内のファイル名でInputStreamを作る

InputStreamは以下のコードでゲット出来る。

InputStream inputStream = getResources().openRawResource(R.raw.test);

int rawID = R.raw.class.getField("text").getInt(null);