カテゴリーアーカイブ Java

村上 著者:村上

【Android】ActionBarのタイトルとボタンの色を白色に変更する

前回に引き続き、今回も Android の ActionBar についての記事です。
今回は、ActionBar の戻るボタンやタイトルの色を白色に変更する方法です。
ActionBar を濃い色で指定しているので、戻るボタンの色を白に変えたかったのですが、どこを直すのかがわかりにくかったのでまとめました。

参考にさせていただいた記事はこちらから。

android – Changing ActionBar Text and Button color when using Theme.AppCompat.Light – Stack Overflow
https://stackoverflow.com/questions/30720873/changing-actionbar-text-and-button-color-when-using-theme-appcompat-light

 

修正するのは、プロジェクトの res > values ディレクトリ内にある styles.xml ファイルです。
このファイル内にある AppTheme という名前のタグの parentTheme.AppCompat.Light.DarkActionBar に変更します。
具体的には下記のとおりです。

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ......
</style>

変更はこれだけで、実機で確認したところ、きちんと白色に変更されていました。

他にも、タグ内に下記を追加するという方法もあるようでしたが、私の環境では上手くいきませんでした。

<item name="android:textColorPrimary">#fff</item>

そのため、他に影響が出ないようでしたら、parent を変更する方法をおすすめします。

 

以上、Android の ActionBar のボタン・タイトルの色を白色に変更する方法でした。
ご参考になれば幸いです。

  • この記事いいね! (0)
村上 著者:村上

【Android】setTitle()で指定したActionBarのTitleが表示されない時の対処法

凄く初歩的ですが、今後も同じミスをやらかしそうな予感がしたので、未来の自分のためにまとめ。
タイトル通り、.setTitle() を使って ActionBar の Title を指定したのに表示されなかった時の対処法です。

今回参考にさせていただいた記事はこちらから。

Android getActionBar().setTitle does not work – Stack Overflow
https://stackoverflow.com/questions/26045431/android-getactionbar-settitle-does-not-work

ちなみに5年前の投稿でしたので、結構古いです。
が、私の環境ではこちらの方法で解決可能でした。

 

対処法ですが、getSupportActionBar().setDisplayShowTitleEnabled(true); を追加するだけでした。
具体的には下記のとおりです。

getSupportActionBar().setDisplayShowTitleEnabled(true);  // この行を追加
getSupportActionBar().setTitle("[タイトル]");

実際に実機(Android 7.0 と 8.0)で試したところ、問題なくタイトルが表示されていました!
念のため、他の端末でも確認する予定ですが、多分問題はないはずです。

 

以上、Android の ActionBar のタイトルが表示されない時の対処法でした。
ご参考になれば幸いです。

  • この記事いいね! (0)
村上 著者:村上

【Android】「Only fullscreen opaque activities can request orientation」エラーでアプリがクラッシュする時の対処法

タイトル通り、今回は Android で発生したエラーの対処法についてです。
以前に開発したアプリの修正を行っていたところ、確か現在の Activity から別の ActivityIntent を使って遷移した際に「java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation」というエラーと共にアプリが強制終了しました。

参考にさせていただいた記事はこちらから。

java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation – Qiita
https://qiita.com/oxsoft/items/042aaa6e9c7ae828e967

全く同じ状況だったので、大変参考になりました…!

 

参考サイトによると、クラッシュ原因は下記の 4つを満たすと発生するそうなので、どれか一つでも対処すればOKです。

  1. Android 8.0 の端末
  2. targetSdkVersion が 27 以上
  3. 背景を透過にしている
  4. 画面の向きを固定している

私は 4番目の「画面の向きを固定している」を変更することで対応しました。
…というか、これを変更する以外の選択肢がないのでは…?

画面の向きを固定しない方法については、下記のサイトを参考にさせていただきました。

Y.A.M の 雑記帳: Android 画面の向きを設定
http://y-anz-m.blogspot.com/2010/09/android.html

設定方法は AndroidManifest.xml 内にある、画面向きを固定しないアクティビティの android:screenOrientationbehind に設定するだけです。
サンプルコードは下記のとおりです。

<activity
    android:name=".[アクティビティ名]"
    android:label="@string/app_name"
    android:screenOrientation="behind" />

対処方法としては以上です。
再度アプリをビルド・実行したところ、クラッシュすることなく問題なく動作しました!

 

以上、「java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation」エラーでアプリがクラッシュする時の対処法でした。
ご参考になれば幸いです。

  • この記事いいね! (0)
asaba 著者:asaba

【androidjava】javaでhtmlタグを操作する

javaでは、Html.fromHtml(何かの変数)メソッドを使うことでhtmlタグでTextView

を操作することが出来ます。

部分的に強調したいところがあったりTextViewをリンクとして

使いたくなった時に色を変えたい時が主な用途です。

まず、sring.xmlで文字を追加します。

 

<pre><string name="sample" translatable="false">※[&lt;font color=\"navy\"&gt;%s&lt;/font&gt;]</string></pre>

 

stringタグを作った後に色を変えたい箇所を&ltと&gtで囲みます。囲まれている

$sが今回表示したい文字になります。

 

color=\”何かの色\の形式で好きな色に変えることができます。

 

続いてxml↓

 

<pre><TextView
    android:id="@+id/text_sample"
    android:layout_width="150sp"
    android:layout_height="wrap_content"
    android:layout_marginStart="10dp"
    android:layout_marginEnd="20dp"
    android:layout_marginTop="110dp"
    android:textColor="#444444"
    android:background="@drawable/selector"
    android:textSize="16sp"
    android:textStyle="bold" /></pre>

 

後にコード上で文字列を入れるのでテキストには何も設定しません。

ですがこれだけではこのまま表示されてしまうので、次にMainActivityに

実際に文字を入れていきます。

 

まず、String.formatでstring.xmlから文字を抽出しています。第一引数

が形式、第二引数が入れたい文字となっております。

次に、入れたい文字列ですが、ここではhogehogeが先ほどのstring.xmlの%sに入っていきます。

 

最後にsetTextの中でHtml.fromHtml(text)でhtmlタグを使って

 


@InjectView(R.id.text_sample)
TextView sampleText;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help);
ButterKnife.inject(this);

String text = String.format(getText(R.string.sample).toString(), "hogehoge");
sampleText.setText(Html.fromHtml(text));
}

 

string.xml内の文字列を翻訳して色が変われば無事終了となります。簡単

なコード数行で済むのでhtml経験者ならもっと自在に扱えそう・・・・。

でもcssなしでここまでカスタマイズできるなら上等かなぁと思います。

  • この記事いいね! (0)
asaba 著者:asaba

【javaライブラリ】picassoがどこから画像を取得したか調べる方法

画像読み込みライブラリのpicassoが便利なのは前のブログで

散々説明してきたので割愛します。

 

今回は、キャッシュした画像はどこから取ってきたかを

調べるためにPicasso.with(getApplicationContext()).setIndicatorsEnabled(true);

を使います。

 

この一行を加えるだけでpicassoがどこを通じてキャッシュしたか

分かるようになります。

例えば、ピカソの画像の左上を見ると

 

 

角の部分が色になっているの

が分かります。

 

これはメモリ経由、つまりメモリ上でキャッシュした画像を

引き出して表示しているという意味合いになります。

 

もともとはこの画像はネットワーク上から取得したのですが、picassoは取得した画像を

指定の場所にキャッシュをするので、必然的にこの画像の発生場所は

メモリ上になるということです。

 

この他にもネットワークから直接持ってきた場合は、ディスクから

持ってきた場合は色の角として表示されます。

 

出自元が分かればそこまで調べる必要はなさそうですが、ダウンロードした

画像がちゃんとキャッシュされているか確認したい場合は使う価値大ですね。

 

 

  • この記事いいね! (0)
asaba 著者:asaba

【java】Fisher-Yatesアルゴリズムで配列を闇鍋状態にする

数あるshuffle法の中で最も分かりやすいかつ速度が安定している

Fisher-Yatesアルゴリズムで値をごちゃまぜにしてみました。

どこまで値を増やしてもO(n)のままなので、速度にこだわらない

のであれば大体これ一択という流れになります。

こちらは、15個の値を順に並べ、シャッフルボタンを

押すと1から順に並んだ値とランダムで出した値を100通り

shuffleしています。

このやり方、先週ブログでも書いた文字列を判定する方法と

似ていますね。これを更に応用してランダムに1番から15番の値を

iが100に達するまで回しています。

100のところは500でも1000でもその限度まで回してくれるので

もっと回したい!というかたはお好みで。

 

<pre>public class MainActivity extends AppCompatActivity {
    int[] data = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
    int[] first = new int[5];
    int[] sec = new int[5];
    int[] drawableIds;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);

        //drawableIds = new int[typedArray.length()];
    }
    @OnClick(R.id.shuffle)
    public void shuffle() {
        Random rand = new Random();
        for(int i = 0; i < 100; i++){
            for(int j =0; j < data.length; j++) {
                int temp;
                int num = rand.nextInt(data.length);
                temp = data[j];
                data[j] = data[num];
                data[num] = temp;
            }
        }
    }
}</pre>

 

更に、このままだとシャッフルしただけで何も面白くないという

ことなので、せっかくなのでカードゲームのように最初の列から

値を5個ずつ取ってみましょう。

まず、一番最初にfirstという配列にドローした値を格納しています。

このfirstはもういじることはないので、次に連続して引きたい時に

先ほど引いた5個の値を後ろに押し戻して次の5個の値を

取り出します。

同時に10列目の値群も動かさないといけないので5の倍数で

動かしていきます。

一通り入れ替えたらSystem.out.printlnをして確認してみましょう。

こちらが確認できれば組立終了です。

 


@OnClick(R.id.take)
public void draw() {
for(int d = 0; d < data.length / 3; d++){
first[d] = data[d];
}
System.out.println(Arrays.toString(first));
for(int s = 0; s < data.length / 3; s++){
int temp;
temp = data[s];
data[s] = data[s+5];
data[s+5] = data[s+10];
data[s+10] = temp;
}
System.out.println(Arrays.toString(data));
}

シャッフルクラスの説明は以上でおしまいです。

これを一つのクラスにまとめればトランプとかボウズめくりの

ための汎用クラスとして使えそうですね。

  • この記事いいね! (0)
asaba 著者:asaba

【java】StringBuilderでデータをまとめてpostで送る

StringBuilderを使ってhttpURLConnectionで好きなだけデータを

postする汎用メソッドを作りました。

 

使い方はシンプルで、ただ拡張for文を使って回すだけなので

特別な制約は無いです。

 

</pre>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

StringBuilder contentsBuilder = new StringBuilder();
Map<String, String> map = new HashMap<>();
String str = "hello!!";
double lat = 34.222222;
double longi = 137.111111;
String line = ",";
String strlati = String.valueOf(lat);
String strlong = String.valueOf(longi);
map.put("string", str);
map.put("latitude", strlati);
map.put("longitude", strlong);
for (String val : map.values()) {
if (contentsBuilder.length() > 0) {
contentsBuilder.append(line);
}
contentsBuilder.append(val);
}
}
<pre>

変数latとlongiはdoubleですが、途中でString.valueOf()で変換することで

送ることができるようになります。

 

もしサーバー側で変換したい場合は、\nとか、ごとに切り分けた後に

各値に合った型に戻してあげればいけそうですね。

 

本当はもっと簡単に書きたかったですがこの辺で妥協します。

  • この記事いいね! (0)
asaba 著者:asaba

【java】ライブラリを使わずに文字列を反転させる

入力した文字列を反転させるミニアプリを作りました。

ライブラリを使えばこんな手間なんてかからないのですが、

なんとなく生のjavaを触って反転させたいと思ったのがきっかけです。

 


public class MainActivity extends AppCompatActivity {
EditText ed;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.altBtn);
ed = findViewById(R.id.mountingText);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String beforeAlterText;
beforeAlterText = ed.getText().toString();
char[] chars = beforeAlterText.toCharArray();
int i = beforeAlterText.length();
if(i % 2 == 0) {
int dev = i / 2;
for(int j = 0; j < dev; j++){
char temp = chars[j];
chars[j] = chars[i – j – 1];
chars[i – j – 1] = temp;
}
System.out.println(chars);

}else if(i % 2 == 1){
int notdev = i / 2 + 1;
for(int j = 0; j < notdev; j++){
char temp = chars[j];
chars[j] = chars[i – j – 1];
chars[i – j – 1] = temp;
}
System.out.println(chars);
}
}
});
}
}


 

最初の分岐で奇数か偶数か判別した後に入力した文字を2で割って中間地点を決めます。

この中間地点まで文字を反転させるといった感じになっています。

 

バブルソートは値の大小を判断しますがここではただの文字列

なのでそのまま文字を置き換えています。

 

文字は出てこないですがSystem.outで反転後の文字列が

確認することができます。

以上ですが見ての通り中身が何もないです。

ttsとか使って応用できればもっと面白そうなアプリが作れるかもしれません。

とりあえずソートの練習をしたいとか見てみたいとか思ったら試してみてください。

 

P.S.余談ですが、自分はこのコードの中で文字列を

退避するところをゴミ箱って呼んでます。

 

  • この記事いいね! (0)
asaba 著者:asaba

【androidjava】Bitmap初期化失敗した時に確認すること

googlemapを使う時にマーカーをカスタマイズしたい時に

bitmapを使うのですが、googlemapと併用する際は

始動時のonMapReadyの中で処理をする必要があります。

 

これは、Google Map の用意が出来た時に初めて初期化できる状態に

なるからです。

 

なのでonCreate内でbitmapを初期化

しようとするとエラー「IBitmapDescriptorFactory is not initialized」

で初期化が失敗してしまいます。

 

</pre>
@Override
public void onMapReady(GoogleMap googleMap) {

//この中でforを使いたい場合

BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(myImageList[i]);

ClusterModel offsetItem = new ClusterModel(title[i],url[i], icon);

}
<pre>

 

なんでもフィールドやonCreate内で初期化するのも

よくないということですね。

  • この記事いいね! (0)
asaba 著者:asaba

【android・googlemap】DefaultClusterRendererをオーバーライドしたカスタマイズ法

DefaultClusterRendererを継承したクラスを作ってオーバーライドして

値を変えることで自分好みのマップを作ることができます。

例えば、addmarkerを使わずにsetInfoWindowAdapterと併用して

マーカーをカスタマイズしたい時は、DefaultClusterRendererを継承した

クラスの中にonBeforeClusterItemRenderedをオーバーライドした

メソッドを書くことでマーカーのアイコンを変更することができます。

 

マーカーを変更したい時はこちらも

お忘れなく。↓

</pre>
public class ClusterModel implements ClusterItem {
private LatLng mPosition;
private String mTitle;
private String mSnippet;
private BitmapDescriptor mIcon;

//一番最後にBitmapDescriptorを追加

public ClusterModel(double lat, double lng, String title, String snippet,BitmapDescriptor icon) {
mPosition = new LatLng(lat, lng);
mTitle = title;
mSnippet = snippet;
mIcon = icon;
}

@Override
public LatLng getPosition() {
return mPosition;
}

@Override
public String getTitle() {
return mTitle;
}

@Override
public String getSnippet() {
return mSnippet;
}
public BitmapDescriptor getIcon() {
return mIcon;
}
}
<pre>

 

こちらはメインアクティビティ↓

 

</pre>
@Override
public void onMapReady(GoogleMap googleMap) {
mMap= googleMap;
//クラスターインスタンス化
mClusterManager = new ClusterManager<ClusterModel>(this, mMap);
mClusterManager.setRenderer(new MarkerRenderer(this, mMap, mClusterManager));
mClusterManager.setOnClusterClickListener(this);
mMap.setOnCameraIdleListener(mClusterManager);
mMap.setOnMarkerClickListener(mClusterManager);
for(int i =0; i < points.size(); i++) {
BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(myImageList[i]);
ClusterModel offsetItem = new ClusterModel(pointX[i], pointY[i],title[i],url[i], icon);
mClusterManager.addItem(offsetItem);
}
}
<pre>

 

アクティビティ内に以下のクラスを追加↓

 

</pre>
private class MarkerRenderer extends DefaultClusterRenderer<ClusterModel>{
public MarkerRenderer(Context context, GoogleMap map, ClusterManager<ClusterModel> clusterManager) {
super(context, map, clusterManager);
}
@Override
protected int getColor(int clusterSize) {
return Color.rgb(0, 255, 255);
}
@Override
public void onBeforeClusterItemRendered(ClusterModel markerItem, MarkerOptions markerOptions) {
if (markerItem.getIcon() != null) {
markerOptions.icon(markerItem.getIcon());
}
markerOptions.visible(true);
}
}
<pre>

 

onBeforeClusterItemRenderedは、アイコンが出る前にrenderする(アイコンの更新

や動きを決める)役割を持ったメソッドです。

つまり、アイコンの見た目を変えたい場合はこちらをオーバーライドして

設置しておけば画像を受け取って変更してくれるという訳です。

 

addmarkerは同期してマーカーがrenderされるので遅い&容量食らうのでメモリ不足

になりがちですが、ClusterManagerと組み合わせて非同期で

renderすることで、マーカー・クラスターが増えても高速でrender

をしてくれるので多少複雑に作ってもこっちを作った方が

よさそうです。

  • この記事いいね! (0)