質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.40%

  • Android

    6862questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android numberpicker カスタム

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 2,063

xasax0404

score 19

Androidで、10,20,30のように選択できるnumberpickerを利用したいです。調べたところ標準では単位の変更は出来ないとの事なのでカスタムされたものを使おうと考えています。
そこで、http://dev.classmethod.jp/smartphone/increment-minutes-custom-timepicker-01/のサイトに乗っているプロジェクトを使用し、既存のプロジェクトに組み込んでみたのですが、やり方が違うのかうまく動作しません。
既存のプロジェクトにサイトのプロジェクトをimport moduleして、使いたい場所のxmlに記述、javaの方にも動作を記述して実行させると、まるで既存のプロジェクトが存在していないかのように、サイトのアプリのみが動きます。
外部からプロジェクトを参照して特定の場所でカスタマイズされたものを使うのは無理なのでしょうか?
長文でわかりにくいかもしれませんが、よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

恐らくサンプルも一緒にimportしてしまっていると思われます。

GitHubからzip形式でダウンロードすると、大まかに以下のような構成になっていると思います。

AndroidComponentLibrary-master
 │
 ├ ComponentLibrary
 │
 └ SampleComponent

Import Moduleする際にAndroidComponentLibrary-masterを選ばれませんでしたか?

![イメージ説明](3d1e5f1ef042109afd5cdbf7c5293dc6.png)

サンプルは必要ないので、図のようにImportのチェックを外してください。

もしくは、Source directoryにAndroidComponentLibrary-master\ComponentLibraryを指定してください。

-追記-
カスタムNumberPickerの作り方

まず、res/valuesにxmlファイルを追加します。
ファイル名は「attr.xml」などとします。
これにより、レイアウトファイルで指定するパラメータを定義します。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomNumberPicker">
        <attr name="step" format="integer" />
        <attr name="min" format="integer" />
        <attr name="max" format="integer" />
    </declare-styleable>
</resources>

続いてJava Classを追加します。
名前はxmlで指定したものと同じ「CustomNumberPicker」で、
SuperclassとしてNumberPickerを指定します。

package xxx;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.v7.widget.AppCompatEditText;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.NumberPicker;

/**
 * Created by massa on 2016/11/15.
 */

public class CustomNumberPicker extends NumberPicker {

    // 表示用の値のリスト
    private String [] mValueSet;

    // 最大値・最小値
    private int mMaxValue;
    private int mMinValue;

    // 刻み幅
    private int mStep;

    public CustomNumberPicker(Context context) {
        super(context);
    }

    public CustomNumberPicker(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context, attrs);
    }

    public CustomNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initialize(context, attrs);
    }

    private void initialize(Context context, AttributeSet attrs) {
        if (this.isInEditMode()) {
            return;
        }

        // レイアウトで指定された値の取得
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomNumberPicker, 0, 0);
        try {
            mStep = typedArray.getInteger(R.styleable.CustomNumberPicker_step, 1);
            mMinValue = typedArray.getInteger(R.styleable.CustomNumberPicker_min, 0);
            mMaxValue = typedArray.getInteger(R.styleable.CustomNumberPicker_max, mMinValue);
        }
        finally {
            typedArray.recycle();
        }

        setValues();
    }

    private void setValues() {
        int value_num = 0;

        // minとmaxが逆だったら入れ替える
        if (mMinValue > mMaxValue) {
            int temp = mMinValue;
            mMinValue = mMaxValue;
            mMaxValue = temp;
        }

        // min ~ maxに値がいくつ入るか算出
        value_num = (mMaxValue - mMinValue + mStep - 1) / mStep;

        mValueSet = new String[value_num + 1];

        // 表示値のリストを作る
        for (int i = 0; i < value_num; i++) {
            mValueSet[i] = String.valueOf(mMinValue + mStep * i);
        }
        mValueSet[value_num] = String.valueOf(mMaxValue);

        // 表示値の数が変わるので、一旦初期化
        super.setMaxValue(0);

        setDisplayedValues(mValueSet);

        // 本来のValueはindexとして使用する
        super.setMinValue(0);
        super.setMaxValue(value_num);

        // 一旦最大値を設定
        super.setValue(value_num);

        for (int i = 0; i < getChildCount(); i++) {
            View view = getChildAt(i);
            if (view.getClass().equals(AppCompatEditText.class) == true) {
                // Text部分のサイズを計算
                int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST);
                view.measure(expandSpec, expandSpec);

                // Text部分の幅を設定
                ViewGroup.LayoutParams params = view.getLayoutParams();
                params.width = view.getMeasuredWidth();
            }
        }

        // 初期表示のindex
        super.setValue(0);
    }

    @Override
    public int getValue() {
        // setDisplayedValuesでも使用しているので、ここに変更は加えない
        return super.getValue();
    }

    @Override
    public void setValue(int value) {
        // スクロール時に使用されているので、ここに変更は加えない
        super.setValue(value);
    }

    public int getDisplayedValue() {
        // 選択されている値を取得するときは、こちらを呼び出す
        int pos = super.getValue();
        return Integer.parseInt(mValueSet[pos]);
    }

    @Override
    public void setDisplayedValue(int value) {
        // プログラム中から表示値の設定をするときは、こちらを呼び出す
        int pos = 0;
        while (value > Integer.parseInt(mValueSet[pos])) {
            pos++;
        }
        super.setValue(pos);
    }

    @Override
    public int getMinValue() {
        return mMinValue;
    }

    @Override
    public void setMinValue(int minValue) {
        mMinValue = minValue;
        setValues();
    }

    @Override
    public int getMaxValue() {
        return mMaxValue;
    }

    @Override
    public void setMaxValue(int maxValue) {
        mMaxValue = maxValue;
        setValues();
    }
}

後は、レイアウトファイルから以下のように使用できると思います。

<xxx.CustomNumberPicker
        xmlns:custom="http://schemas.android.com/apk/res-auto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        custom:step="5"
        custom:min="10"
        custom:max="100"
        android:id="@+id/numberPicker"/>

選択されている値は、以下のように取得できます。

CustomNumberPicker customNumberPicker = (CustomNumberPicker)findViewById(R.id.numberPicker);

int value = customNumberPicker.getDisplayedValue();


当初、getValue()をオーバーライドしてみたのですが、
setDisplayedValuesの中から呼び出されているようで、表示される値がおかしくなってしまいました。
なので、getValue()はいじらず、getDisplayedValue()というメソッドを追加しています。

パッケージ名はxxxとしているので、適宜変更してください。
色々なケースを試せてないので、問題あればご指摘ください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/14 15:01

    ところで、このライブラリにあるのはカスタムTimePickerだけのようですが、
    利用したいのはNumberPickerですよね?
    そのあたりは問題ないでしょうか?

    キャンセル

  • 2016/11/14 19:27

    サイトにあるピッカーのように、5,10,15のように指定出来れば、その派生で10,20,30と出来ると考えてこのプロジェクトを利用しようとしてますが、timepickerはnumberpickerのように利用する事は出来ないのでしょうか?

    キャンセル

  • 2016/11/15 14:59

    TimePickerはあくまでも時刻を入力するためのインターフェイスなので、
    時、分の2つのNumberPickerが表示されてしまいます。
    また、値の範囲も0~23と0~59になってしまいます。

    NumberPickerを基にカスタムViewを作成したほうが良いかと思われます。
    試しに作ってみたので、最初の回答に追記しました。

    キャンセル

  • 2016/11/17 16:33

    自分の求めていたとおりの動作しました!
    ほんとに感謝しています。

    キャンセル

  • 2016/11/29 15:30

    すいません、解決した報告したものを再度質問するのはよろしくないんですが、聞いて下さい。
    様々な端末でこのカスタムピッカーを使用しましたが、apiが15以下だとうまく動作しないみたいです。解決策わかりますでしょうか?

    キャンセル

  • 2016/11/30 18:30

    遅くなりましたが、修正してみました。
    (1) initialize
    レイアウトが表示されなくなっていたので、編集時にはそれ以降の処理を行わないようにしました。

    (2) setValues
    API16以降(?)では数字の部分の幅が自動的に調整されるようですが、
    API15のADBで確認したところ、はみ出してしまっていたので調整するようにしました。

    (3) setValue、setDisplayedValue
    API15以前ではスクロール時にsetValueが呼ばれているようで、
    ここをカスタマイズしていたためスクロールがうまくできなくなっていました。
    なので、setValueはIndexを指定するメソッド、setDisplayedValueは表示値を設定するメソッドという形にしました。

    キャンセル

0

マニフェストファイルもコピーしましたか?
起動Activityがサンプルのものになっているのかも知れませんね。
マニフェストファイルを追記してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

Androidで、10,20,30のように選択できるnumberpicker

標準では単位の変更は出来ないとの事なので

NumberPickerをこの場合2つ並べれば簡単にできると思います

NumberPicker numPicker0 = (NumberPicker)findViewById(R.id.numPicker0);
NumberPicker numPicker1 = (NumberPicker)findViewById(R.id.numPicker1);


numPicker0.setMaxValue(3);
numPicker0.setMinValue(1);

numPicker1.setMaxValue(0);
numPicker1.setMinValue(0);        


numPicker0は1,2,3
numPicker1は0固定

これでnumPicker0だけをユーザーが動かせばできるでしょう
参考:
https://akira-watson.com/android/numberpicker.html

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/14 19:21

    すみません。そのような方法も検討しましたが、100以上も考えてますので今回は辞めたんです。説明不足ですみませんでした。

    キャンセル

  • 2016/11/14 22:43

    100以上でもnumberPicker0の上限を10以上にすればいいのでは?

    キャンセル

  • 2016/11/15 00:43

    100以上とは?
    110... 250...3660, というようなpickerでしょうか
    [1][1][0]と3つ、4つと桁を増やして並べれば済むのでは
    あるいは何か他に理由があるのでしょう

    キャンセル

同じタグがついた質問を見る

  • Android

    6862questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。