ページ 11

【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月15日(月) 07:29
by 幾三
Androidアプリケーション開発での質問です
activity_main.xmlにボタンやチェックボックスなどのViewを沢山配置した際、
一つ一つの操作をMainActivity.java内に書く訳にも行かないので
別のクラスから操作しようと思ったのですが方法が分からず困っています。

例えば
activity_main.xmlにButtonを用意し、
MainActivityを継承したButtonManager.javaからfindViewById()でボタンを取得
そのクラス内に「ボタンが押されたらToast()を表示」的な処理をOnClickListenerを使用して書き
MainActivity.javaにはButtonManager bmgr = new ButtonManager(this)
を記述
また、Button.setOnClickListener(this);とだけ書かれたbmgr.ser()も記述

と言う感じで出来ないかと試みたのですが起動すらされませんでした…

MainActivity以外からactivity_main.xmlにあるViewの操作を行うことは
実際可能でしょうか?
であればどう処理を記述すればいいのかご教授願いたいです

よろしくおねがいします

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月15日(月) 12:00
by softya(ソフト屋)
MainActivity以外からactivity_main.xmlにあるViewの操作を行うことは実際可能でしょうか?
可能ですが、ButtonManagerのプログラムの組み方次第です。
今出されている情報だと何とも言えません。

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月15日(月) 15:49
by 幾三
申し訳ないです、以下ソースになります

MainActivity.java

コード:

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		ButtonManager mgr = new ButtonManager(this);
		mgr.set();
		
	}

}
ButtonManager.java

コード:

public class ButtonManager extends MainActivity implements OnClickListener {
	
	Button btn;
	RadioGroup radio_g;
	
	public ButtonManager(Context context){
		LayoutInflater inf = LayoutInflater.from(context);
		View infView = inf.inflate(R.layout.activity_main, null);
		
		btn = (Button)infView.findViewById(R.id.button1);
		radio_g = (RadioGroup)infView.findViewById(R.id.radioGroup1);
		
	}
	
	public void set(){
		btn.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
//		radio_g.setVisibility(VISIBLE);		← なぜかVISIBLEが定義されていない
		Toast.makeText(this, "表示されました。", Toast.LENGTH_LONG ).show();
	}
	
}
activity_main.xml

コード:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.te.MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Button" />

    <RadioGroup
        android:id="@+id/radioGroup1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:visibility="gone">

        <RadioButton
            android:id="@+id/radio0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="RadioButton" />

        <RadioButton
            android:id="@+id/radio1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="RadioButton" />
    </RadioGroup>

</RelativeLayout>
activity_main.xmlに定義されたRadioGroupをButtonのクリックによって表示させるような事をしたいのですが
RadioGroupのsetVisibility()にGONEやVISIBLEが設定できなかったり、Toastすら表示されずの状況です。
このような分け方はやはりプログラムとして正しくないでしょうか?

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月15日(月) 19:02
by hide
なにやら面白いコードになっている感があるのですが
そもそもjavaの知識は問題ないのですか?

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月15日(月) 20:03
by softya(ソフト屋)
現状たとMainActivity と別のアクティビティを作って別のViewも作ってます。
画面に表示されているものと別オブジェクトなので、画面とは一切関わりないためボタンを押しても反応しません。

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月15日(月) 20:43
by 幾三
>なにやら面白いコードになっている感があるのですが
>そもそもjavaの知識は問題ないのですか?
(コンソール画面でやるような)java自体の知識は問題ないと思います。。。
しかしandroid開発でのjavaの知識は全くと言っていいほどの初心者です、すみません・・・

>現状たとMainActivity と別のアクティビティを作って別のViewも作ってます。
>画面に表示されているものと別オブジェクトなので、画面とは一切関わりないためボタンを押しても反応しません。

MainActivityを継承してる時点でそのような気はしていました・・・
下記のサイトを見て参考にしてみたのですが用途(?)が違ったのですかね
http://moltuchinia.cocolog-nifty.com/bl ... id-97.html
僕の望む処理を行うにはどのようなことが必要になるでしょうか?
アドバイスお願いします。。。

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月15日(月) 21:48
by hide
コンソールのみの経験だとなかなか大変かもしれないですね。
LayoutInflatorは結構難しいですので慣れてからのほうがいいです。

こういうイメージでしょうか。コンパイルすら通してないのでそのままは動かないと思います

コード:

public class MainActivity extends Activity
{
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Button button = (Button) findViewById(R.id.button1);
		RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radio1);
		
		new Button1Listener(button, radioGroup);
	}
}

コード:

public class Button1Listener implements View.OnClickListener
{
	private RadioGroup radioGroup;
	
	public Button1Listener(Button button, RadioGroup radioGroup)
	{
		this.radioGroup = radioGroup;
		button.setOnClickListener(this);
	}
	
	@Override
	public void onClick(View view)
	{
		radioGroup.setVisibility(View.INVISIBLE);
	}
}

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月15日(月) 23:10
by 幾三
hideさんありがとうございます
RadioGroupの表示非表示は反応しませんでしたが
コンストラクタで同時にContextを受け取るようにすると
ボタンクリックでトーストを表示させることは出来ました!

先ほどのコードはこういう事がしたいという例えでして、実際に作ろうと考えているアプリケーションのactivity_main.xmlは以下のようになっています。
(ID名やTextなどの値を直接書いている点は無視してください・・・)
これらを制御するのにMainActivity.javaからViewを取得しようとすると、findViewById()だけで何十行にもなりそうなので
それを回避したいと思い別ファイルでfindViewById()処理をしたかったのですが・・・

コード:

<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.MainActivity" >

    <TextView
        android:id="@+id/ActivityTitleBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:background="#ff364353"
        android:gravity="center"
        android:padding="20dp"
        android:text="設 定"
        android:textColor="#ffffffff"
        android:textSize="35sp" />

    <LinearLayout
        android:id="@+id/DoubleButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:background="#ff364353"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/wBtn_Reset"
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_weight="0.99"
            android:background="@drawable/doublebutton"
            android:text="リセット"
            android:textColor="#ffffffff"
            android:textSize="20sp" />

        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:layout_marginBottom="15dp"
            android:layout_marginTop="15dp"
            android:background="#ff58adba" />

        <Button
            android:id="@+id/wBtn_OK"
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:layout_weight="0.99"
            android:background="@drawable/doublebutton"
            android:text="確定"
            android:textColor="#ffffffff"
            android:textSize="20sp" />
    </LinearLayout>

    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/DoubleButton"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/ActivityTitleBar" >
        
        <yanzm.products.customview.RelativeRadioGroup
            android:id="@+id/radioGroup1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp" >
            
            <TextView
		        android:id="@+id/text"
		        android:layout_width="match_parent"
		        android:layout_height="30dp"
		        android:layout_alignParentTop="true"
		        android:background="@drawable/text"
		        android:gravity="center_vertical"
		        android:text="食材を指定してね。"
		        android:textColor="#ffffffff" />

            <RadioButton
                android:id="@+id/radio0"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_below="@+id/text"
                android:layout_alignRight="@+id/radio1"
                android:layout_marginTop="10dp"
                android:background="@drawable/radiobutton"
                android:button="@null"
                android:text="肉類"
                android:textSize="20sp" />

			<LinearLayout
			    android:id="@+id/AnimLay1" 
			    android:layout_width="wrap_content"
	            android:layout_height="wrap_content"
	            android:layout_alignParentLeft="true"
	            android:layout_alignParentRight="true"
                android:layout_below="@+id/radio0" >
	            <RelativeLayout
	                android:id="@+id/Layout1"
	                android:layout_width="match_parent"
	                android:layout_height="wrap_content"
	                android:background="@drawable/checkgroup" >
	
	                <LinearLayout

<!--		省略		-->

			           	<CheckBox
			           	    android:id="@+id/r5_element1"
			           	    android:layout_width="match_parent"
			           	    android:layout_height="wrap_content"
			           	    android:layout_weight="1"
			           	    android:background="@drawable/checkbutton"
			           	    android:layout_marginTop="2dp"
							android:layout_marginLeft="4dp"
							android:layout_marginRight="4dp"
							android:layout_marginBottom="2dp"
							android:button="@null"
			           	    android:text="マヨネーズ" />
			           	
			           	<CheckBox
			           	    android:id="@+id/r5_element2"
			           	    android:layout_width="match_parent"
			           	    android:layout_height="wrap_content"
			           	    android:layout_weight="1"
			           	    android:background="@drawable/checkbutton"
			           	    android:layout_marginTop="2dp"
							android:layout_marginLeft="4dp"
							android:layout_marginRight="4dp"
							android:layout_marginBottom="2dp"
							android:button="@null"
			           	    android:text="ケチャップ" />
					</LinearLayout>
	
					<LinearLayout
	 	  	                    android:id="@+id/r5_lay2"
					    android:layout_width="match_parent"
					    android:layout_height="wrap_content"
					    android:layout_below="@+id/r5_lay1"
					    android:background="@drawable/checkgroup"
					    android:orientation="horizontal" >
	
			           	<CheckBox
							android:id="@+id/r5_element3"
							android:layout_width="match_parent"
							android:layout_height="wrap_content"
							android:layout_weight="1"
							android:background="@drawable/checkbutton"
							android:layout_marginTop="2dp"
							android:layout_marginLeft="4dp"
							android:layout_marginRight="4dp"
							android:layout_marginBottom="2dp"
							android:button="@null"
							android:text="みりん" />
		
			           	<CheckBox
			           	    android:id="@+id/r5_element4"
			           	    android:layout_width="match_parent"
			           	    android:layout_height="wrap_content"
			           	    android:layout_weight="1"
			           	    android:background="@drawable/checkbutton"
			           	    android:layout_marginTop="2dp"
							android:layout_marginLeft="4dp"
							android:layout_marginRight="4dp"
							android:layout_marginBottom="2dp"
							android:button="@null"
			           	    android:text="でんぷん" />
			           	
			           	<CheckBox
			           	    android:id="@+id/r5_element5"
			           	    android:layout_width="match_parent"
			           	    android:layout_height="wrap_content"
			           	    android:layout_weight="1"
			           	    android:background="@drawable/checkbutton"
			           	    android:layout_marginTop="2dp"
							android:layout_marginLeft="4dp"
							android:layout_marginRight="4dp"
							android:layout_marginBottom="2dp"
							android:button="@null"
			           	    android:text="生もの" />
					</LinearLayout>
				</RelativeLayout>
			</LinearLayout>
        </yanzm.products.customview.RelativeRadioGroup>

    </ScrollView>

</RelativeLayout>
<!-- ここまで1171行/View数100個くらい -->
そもそも、一つのactivity_main.xml内に必要なViewをぎっちり詰め込むのは正しいのでしょうか?
またMainActivity.javaはあくまで大まかな処理の流れ(サブクラスのインスタンス化など)を記述する場所であり
Viewの読み込みや処理を記述するのはサブクラスから、という考えで開発をするのは間違っているでしょうか・・・

など色々疑問点はありますが、取りあえずMainActivity.java以外からactivity_main.xmlのViewを取得し制御出来るようになりたいです。。。
よろしくお願いします。

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月16日(火) 00:00
by hide
それぞれのクラスからfindViewByIdをしたいのであれば
一番上のルートのLayoutにIDを付けてActivityでfindViewByIdで取得し、
そのLayoutをそれぞれのクラスに渡し、layout.findViewByIdですかね(findViewByIdはViewGroupのメソッド)
id付けなくてもルートを取得する方法はあったかもしれないです。

コード:

public class MainActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        ViewGroup viewGroup = (ViewGroup) findViewById(R.id.root); //一番上のlayout
       
        new ClassA(viewGroup);
    }
}

コード:

public class ClassA
{
    public ClassA(ViewGroup viewGroup)
    {
        viewGroup.findViewById( /* R.id.なんとかかんとか */);
    }
}
RadioGroupが消えないのは子ViewのRadioButtonもinvisibleにしないといけないのかな・・・
すみません最近全然androidいじってないもので。

レイアウトのxmlはincludeタグを利用すれば分割出来ます。
ただ、あまり階層を増やさないほうがいいかもしれないです。少し前の機種だとすぐオーバーフローしてましたし、
1画面の情報量が多すぎるのもアプリとして考えものです。

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月16日(火) 01:26
by 幾三
hideさんありがとうございます!何とか出来ました!

以下ソースです、
MainActivity.java

コード:

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		ViewGroup viewGroup = (ViewGroup)findViewById(R.id.layout);
				
		new ButtonManager(this,viewGroup);
	}

}
ButtonManager.java

コード:

public class ButtonManager implements OnClickListener {
	
	Button btn;
	RadioGroup rg;
	Context c;
	
	public ButtonManager(Context context,ViewGroup viewGroup){
		c = context;
		btn = (Button)viewGroup.findViewById(R.id.button1);
		rg  = (RadioGroup)viewGroup.findViewById(R.id.radioGroup1);
		
		rg.setVisibility(View.GONE);
		btn.setOnClickListener(this);
	}
	
	@Override
	public void onClick(View v) {
		rg.setVisibility(View.VISIBLE);
		Toast.makeText(c, "一応押されたよ", Toast.LENGTH_LONG).show();
	}
	
}
activity_main.xml

コード:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.te.MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Button" />

	    <RadioGroup
	        android:id="@+id/radioGroup1"
	        android:layout_width="wrap_content"
	        android:layout_height="wrap_content"
	        android:layout_alignLeft="@+id/button1"
	        android:layout_below="@+id/button1"
	        android:visibility="gone" >
	
	        <RadioButton
	            android:id="@+id/radio0"
	            android:layout_width="wrap_content"
	            android:layout_height="wrap_content"
	            android:checked="true"
	            android:text="RadioButton" />
	
	        <RadioButton
	            android:id="@+id/radio1"
	            android:layout_width="wrap_content"
	            android:layout_height="wrap_content"
	            android:text="RadioButton" />
	        
	    </RadioGroup>

</RelativeLayout>
ボタンでToastの表示も出来ましたし
原因はわかりませんが言われた通りに組んだところRadioGroupの表示切替も無事に出来ました。

xmlも今回初めて触りますので分からないところは多々ありますが
includeタグによるxmlファイルの分割や良いレイアウトの方法含め色々勉強していきたいと思います。

アドバイス下さいましたhideさんとsoftyaさんありがとうございました!

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月16日(火) 10:01
by softya(ソフト屋)
解決してますが、xml自体もaddViewで追加する形にすればxmlにたくさん書く必要はないですよ。
あと配列とリスナを無名クラスで処理すれば、クラス分けする必要さえないかもしれません。

Re: 【Android】MainActivity以外からViewを操作したい

Posted: 2014年12月16日(火) 17:58
by ISLe()
layout(xml)の変更が、ActivityとButtonManager両方に影響しますよね。

ButtonManagerでinflateして、Activityではそれを受け取って、setContentViewすれば良いのでは。
そうしたら、layoutの影響受けるのはButtonManagerだけになります。

softyaさんが書かれているようにlayoutを分割して、それぞれ対応するManagerが処理するというふうにもできます。