Урок 10. Оптимизируем реализацию обработчиков.

Обсуждение уроков
Аватара пользователя
Leeroy
Сообщения: 67
Зарегистрирован: 12 дек 2013, 21:25

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Leeroy » 15 апр 2014, 12:09

Отлично! Спасибо. А вот вопрос на счет if:
Я вот сделал их 5 штук для разных кнопок
if (v.getId() == R.id.button1) textView.setText("button1");
....
else if (v.getId() == R.id.button5) textView.setText("button5");

И все хорошо, eclipse не ругается и программа срабатывает. Правильно ли так или так на самом деле не стоит делать?
Не стоит, код некрасивый.
Я также попробовал убрать else и стало просто все if - и программа без ошибок сохранилась и запускается. Нормально ли это? :)
if (v.getId() == R.id.button1) textView.setText("button1");
......
if (v.getId() == R.id.button5) textView.setText("button5");


Вы сообщили о том, что "Если кнопок меньше 3-х можно и без свича", а ведь вот вставляется 5 кнопок через if и работает. Нужен ли свитч тогда? Если да, тогда как он прописывается в таком случае? Благодарю.
Тебе надо прочитать про управляющие операторы (if, else if, swith ...) это не только ява/андроид это вообще основа всего программирования в целом.
У свича стандартная конструкция, не зависящая от количества кнопок:
для 5 будет тоже что и для 3-х только на 2 кейса больше

Код: Выделить всё


......
case R.id.кнопка4:
do Something
break;
case: R.id.кнопка5:
do Something
break;
Java Core -> JDBC -> GoF -> Android SDK ->...
Телепрограмма в твоем смарте Телепрограмма

Аватара пользователя
xamak
Сообщения: 15
Зарегистрирован: 14 апр 2014, 03:05

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение xamak » 15 апр 2014, 15:01

Vikky_Leto писал(а):Добрый день!
Приложение вылетает. Может кто-то посмотреть в чем ошибка?
Хотя, по логике, вроде все верно.
Manifest:

Код: Выделить всё

[syntax=java]<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ru.startandroid.p0103"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="10" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="ru.startandroid.p0103.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>[/syntax]
MainActivity:

Код: Выделить всё

[syntax=java]
package ru.startandroid.p0103;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity implements OnClickListener{

	Button btnStart;
	TextView tvOut;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//btnStart = (Button) findViewById(R.id.btnStart);
		//tvOut = (TextView) findViewById(R.id.tvOut);
		

		if (savedInstanceState == null) {
			getSupportFragmentManager().beginTransaction()
					.add(R.id.container, new PlaceholderFragment()).commit();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);
			return rootView;
		}
	}

	@Override
	public void onClick(View arg0) {
		tvOut.setText("Нажата кнопка");
		
	}

}

[/syntax]
Fragment_main.xml:

Код: Выделить всё

[syntax=java]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    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="ru.startandroid.p0103.MainActivity$PlaceholderFragment" >

    <Button
        android:id="@+id/btnStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginTop="100dp"
        android:text="start" 
        android:onClick="onClickStart"/>

    <TextView
        android:id="@+id/tvOut"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="TextView" />

</LinearLayout>

[/syntax]
В кнопке "onClickStart", а в методе "onClick". Ну, а если бы лог предоставили, тогда было б легче определить где ошибка.

Аватара пользователя
Leeroy
Сообщения: 67
Зарегистрирован: 12 дек 2013, 21:25

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Leeroy » 15 апр 2014, 19:24

Vikky_Leto писал(а):Добрый день!
Приложение вылетает. Может кто-то посмотреть в чем ошибка?
Хотя, по логике, вроде все верно.
Назови правильно метод (как в xml) onClickStart
И раскомментируй код

Код: Выделить всё

btnStart = (Button) findViewById(R.id.btnStart); 
tvOut = (TextView) findViewById(R.id.tvOut);
Java Core -> JDBC -> GoF -> Android SDK ->...
Телепрограмма в твоем смарте Телепрограмма

Vikky_Leto
Сообщения: 4
Зарегистрирован: 12 апр 2014, 22:05

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Vikky_Leto » 17 апр 2014, 19:05

Благодарю всех за ответы. Исправила ошибки, но приложение по прежнему вылетает
MainActivity:

Код: Выделить всё

[syntax=java]
package ru.startandroid.p0101_listener_beta01;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {
	   TextView tvOut;
	   Button btnOk;
	   Button btnCancel;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

	     tvOut = (TextView) findViewById(R.id.tvOut);
	     btnOk = (Button) findViewById(R.id.btnOk);
	     btnCancel = (Button) findViewById(R.id.btnCancel);
	     
	     OnClickListener oclBtn = new OnClickListener() {
	         @Override
	         public void onClick(View v) {
	           // TODO Auto-generated method stub
	   
	        	// по id определеяем кнопку, вызвавшую этот обработчик
	             switch (v.getId()) {
	             case R.id.btnOk:
	               // кнопка ОК
	               tvOut.setText("Нажата кнопка ОК");
	               break;
	             case R.id.btnCancel:
	               // кнопка Cancel
	               tvOut.setText("Нажата кнопка Cancel");
	               break;
	             }
	         }
	       };
	       
	       btnOk.setOnClickListener(oclBtn);
	       btnCancel.setOnClickListener(oclBtn);
	       
		if (savedInstanceState == null) {
			getSupportFragmentManager().beginTransaction()
					.add(R.id.container, new PlaceholderFragment()).commit();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);
			return rootView;
		}
	}

}
[/syntax]
fragment_main

Код: Выделить всё

[syntax=java]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    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="ru.startandroid.p0101_listener_beta01.MainActivity$PlaceholderFragment" >

    <LinearLayout
        android:id="@+id/linearLayout1"
		android:layout_height="match_parent"
		android:orientation="vertical"
		android:layout_width="match_parent"
		android:layout_margin="30dp" >
		
      <TextView
			android:layout_width="wrap_content"
			android:text="TextView"
			android:layout_height="wrap_content"
			android:id="@+id/tvOut"
			android:layout_gravity="center_horizontal"
			android:layout_marginBottom="50dp">
		</TextView>
		<Button
			android:layout_height="wrap_content"
			android:layout_gravity="center_horizontal"
			android:id="@+id/btnOk"
			android:text="OK"
			android:layout_width="100dp">
		</Button>
		<Button
			android:layout_height="wrap_content"
			android:layout_gravity="center_horizontal"
			android:id="@+id/btnCancel"
			android:text="Cancel"
			android:layout_width="100dp">
		</Button>   
    </LinearLayout>

</LinearLayout>

[/syntax]
Manifest:

Код: Выделить всё

[syntax=java]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ru.startandroid.p0101_listener_beta01"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="ru.startandroid.p0101_listener_beta01.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>
[/syntax]
+ Log:
  • 04-17 16:07:14.297: D/AndroidRuntime(341): Shutting down VM
    04-17 16:07:14.297: W/dalvikvm(341): threadid=1: thread exiting with uncaught exception (group=0x40015560)
    04-17 16:07:14.327: E/AndroidRuntime(341): FATAL EXCEPTION: main
    04-17 16:07:14.327: E/AndroidRuntime(341): java.lang.RuntimeException: Unable to start activity ComponentInfo{ru.startandroid.p0101_listener_beta01/ru.startandroid.p0101_listener_beta01.MainActivity}: java.lang.NullPointerException
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.os.Handler.dispatchMessage(Handler.java:99)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.os.Looper.loop(Looper.java:123)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.main(ActivityThread.java:3683)
    04-17 16:07:14.327: E/AndroidRuntime(341): at java.lang.reflect.Method.invokeNative(Native Method)
    04-17 16:07:14.327: E/AndroidRuntime(341): at java.lang.reflect.Method.invoke(Method.java:507)
    04-17 16:07:14.327: E/AndroidRuntime(341): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    04-17 16:07:14.327: E/AndroidRuntime(341): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    04-17 16:07:14.327: E/AndroidRuntime(341): at dalvik.system.NativeStart.main(Native Method)
    04-17 16:07:14.327: E/AndroidRuntime(341): Caused by: java.lang.NullPointerException
    04-17 16:07:14.327: E/AndroidRuntime(341): at ru.startandroid.p0101_listener_beta01.MainActivity.onCreate(MainActivity.java:47)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
    04-17 16:07:14.327: E/AndroidRuntime(341): ... 11 more

    04-17 16:07:18.567: I/Process(341): Sending signal. PID: 341 SIG: 9

Аватара пользователя
xamak
Сообщения: 15
Зарегистрирован: 14 апр 2014, 03:05

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение xamak » 17 апр 2014, 19:25

Vikky_Leto писал(а):Благодарю всех за ответы. Исправила ошибки, но приложение по прежнему вылетает
MainActivity:

Код: Выделить всё

[syntax=java]
package ru.startandroid.p0101_listener_beta01;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {
	   TextView tvOut;
	   Button btnOk;
	   Button btnCancel;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

	     tvOut = (TextView) findViewById(R.id.tvOut);
	     btnOk = (Button) findViewById(R.id.btnOk);
	     btnCancel = (Button) findViewById(R.id.btnCancel);
	     
	     OnClickListener oclBtn = new OnClickListener() {
	         @Override
	         public void onClick(View v) {
	           // TODO Auto-generated method stub
	   
	        	// по id определеяем кнопку, вызвавшую этот обработчик
	             switch (v.getId()) {
	             case R.id.btnOk:
	               // кнопка ОК
	               tvOut.setText("Нажата кнопка ОК");
	               break;
	             case R.id.btnCancel:
	               // кнопка Cancel
	               tvOut.setText("Нажата кнопка Cancel");
	               break;
	             }
	         }
	       };
	       
	       btnOk.setOnClickListener(oclBtn);
	       btnCancel.setOnClickListener(oclBtn);
	       
		if (savedInstanceState == null) {
			getSupportFragmentManager().beginTransaction()
					.add(R.id.container, new PlaceholderFragment()).commit();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);
			return rootView;
		}
	}

}
[/syntax]
fragment_main

Код: Выделить всё

[syntax=java]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    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="ru.startandroid.p0101_listener_beta01.MainActivity$PlaceholderFragment" >

    <LinearLayout
        android:id="@+id/linearLayout1"
		android:layout_height="match_parent"
		android:orientation="vertical"
		android:layout_width="match_parent"
		android:layout_margin="30dp" >
		
      <TextView
			android:layout_width="wrap_content"
			android:text="TextView"
			android:layout_height="wrap_content"
			android:id="@+id/tvOut"
			android:layout_gravity="center_horizontal"
			android:layout_marginBottom="50dp">
		</TextView>
		<Button
			android:layout_height="wrap_content"
			android:layout_gravity="center_horizontal"
			android:id="@+id/btnOk"
			android:text="OK"
			android:layout_width="100dp">
		</Button>
		<Button
			android:layout_height="wrap_content"
			android:layout_gravity="center_horizontal"
			android:id="@+id/btnCancel"
			android:text="Cancel"
			android:layout_width="100dp">
		</Button>   
    </LinearLayout>

</LinearLayout>

[/syntax]
Manifest:

Код: Выделить всё

[syntax=java]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ru.startandroid.p0101_listener_beta01"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="ru.startandroid.p0101_listener_beta01.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>
[/syntax]
+ Log:
  • 04-17 16:07:14.297: D/AndroidRuntime(341): Shutting down VM
    04-17 16:07:14.297: W/dalvikvm(341): threadid=1: thread exiting with uncaught exception (group=0x40015560)
    04-17 16:07:14.327: E/AndroidRuntime(341): FATAL EXCEPTION: main
    04-17 16:07:14.327: E/AndroidRuntime(341): java.lang.RuntimeException: Unable to start activity ComponentInfo{ru.startandroid.p0101_listener_beta01/ru.startandroid.p0101_listener_beta01.MainActivity}: java.lang.NullPointerException
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.os.Handler.dispatchMessage(Handler.java:99)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.os.Looper.loop(Looper.java:123)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.main(ActivityThread.java:3683)
    04-17 16:07:14.327: E/AndroidRuntime(341): at java.lang.reflect.Method.invokeNative(Native Method)
    04-17 16:07:14.327: E/AndroidRuntime(341): at java.lang.reflect.Method.invoke(Method.java:507)
    04-17 16:07:14.327: E/AndroidRuntime(341): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    04-17 16:07:14.327: E/AndroidRuntime(341): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    04-17 16:07:14.327: E/AndroidRuntime(341): at dalvik.system.NativeStart.main(Native Method)
    04-17 16:07:14.327: E/AndroidRuntime(341): Caused by: java.lang.NullPointerException
    04-17 16:07:14.327: E/AndroidRuntime(341): at ru.startandroid.p0101_listener_beta01.MainActivity.onCreate(MainActivity.java:47)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    04-17 16:07:14.327: E/AndroidRuntime(341): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
    04-17 16:07:14.327: E/AndroidRuntime(341): ... 11 more

    04-17 16:07:18.567: I/Process(341): Sending signal. PID: 341 SIG: 9
Ну, первое, что я увидел, это то, что View-элементы у тебя в fragment_main, а ищешь ты их в activity_main.
Для начала перемести их из fragment_main в activity_main и запусти.

Вот я запустил у себя и все заработало, вот только заменил "public class MainActivity extends ActionBarActivity" на "public class MainActivity extends Activity".

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Foenix » 17 апр 2014, 22:03

Ссылка в подписи
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Vikky_Leto
Сообщения: 4
Зарегистрирован: 12 апр 2014, 22:05

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Vikky_Leto » 17 апр 2014, 23:11

xamak писал(а): Ну, первое, что я увидел, это то, что View-элементы у тебя в fragment_main, а ищешь ты их в activity_main.
Для начала перемести их из fragment_main в activity_main и запусти.

Вот я запустил у себя и все заработало, вот только заменил "public class MainActivity extends ActionBarActivity" на "public class MainActivity extends Activity".
Проблема решена. Работает и без замены на " public class MainActivity extends Activity". Где-то писали, что после обновлений размещать объекты нужно на fragment_main. Вот я и упорно пыталась это сделать.
Всем спасибо за ответы.

BAHINSON
Сообщения: 10
Зарегистрирован: 28 фев 2014, 21:03

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение BAHINSON » 18 апр 2014, 22:23

Помогите пжл.
public class MainActivity extends Activity {

TextView tvOut;
Button btnOk;
Button btnCancel;


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


tvOut = (TextView) findViewById(R.id.tvOut);
btnOk = (Button) findViewById(R.id.btnOk);
btnCancel = (Button) findViewById(R.id.btnCancel);


OnClickListener oclBtn = new OnClickListener() {
@Override
public void onClick(View v) {


}
}

}




public void onClick(View v) {

switch (v.getId()) {
case R.id.btnOk:

tvOut.setText("Нажата кнопка ОК");
break;


case R.id.btnCancel:

tvOut.setText("Нажата кнопка Cancel");
break;

}
}



btnOk.setOnClickListener(oclBtn);
btnCancel.setOnClickListener(oclBtn);
}
}

}



Логи:
Multiple markers at this line
- Syntax error on token "oclBtn", VariableDeclaratorId expected after
this token
- oclBtn cannot be resolved to a variable
- Syntax error on token(s), misplaced construct(s)



Syntax error on token "}", { expected
Вложения
75e947e0469bd053b7bd641fb886e865.png
75e947e0469bd053b7bd641fb886e865.png (15.85 КБ) 14477 просмотров

Donart
Сообщения: 114
Зарегистрирован: 06 ноя 2013, 08:59

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Donart » 19 апр 2014, 11:04

BAHINSON писал(а):Помогите пжл.
У вас два метода onClick. Внимательней на скобки и расположение блоков кода в них.

BAHINSON
Сообщения: 10
Зарегистрирован: 28 фев 2014, 21:03

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение BAHINSON » 19 апр 2014, 15:49

Donart писал(а):
BAHINSON писал(а):Помогите пжл.
У вас два метода onClick. Внимательней на скобки и расположение блоков кода в них.

Рахмет

shyrick
Сообщения: 5
Зарегистрирован: 28 май 2014, 16:31

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение shyrick » 30 май 2014, 10:38

Вопрос возник по третьему методу. Вызов OnClick из xml.

Хочется чтоб данный метод работал если элементы расположены в fragment_main.

Но при попытки разместить обработчик нажатия в

Код: Выделить всё

 public static class PlaceholderFragment extends Fragment {
    	   
    	   TextView tvOut;
    	   Button btnStart;
    	   
        public PlaceholderFragment() { 
        	
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
                
                public void onClickStart(View v) {
            	tvOut.setText("Нажата кнопка start");
              }
  
            return rootView;
        }
    
        
    }
Ругаеться
Multiple markers at this line
- Syntax error on token "(", ; expected
- Syntax error on token ")", ; expected
- void is an invalid type for the variable
onClickStart
а если сделать так

Код: Выделить всё

 public static class PlaceholderFragment extends Fragment {
    	   
    	   TextView tvOut;
    	   Button btnStart;
    	   
        public PlaceholderFragment() { 
        	
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            
           
            
            return rootView;
        }
    
        public void onClickStart(View v) {
        	tvOut.setText("Нажата кнопка start");
          } 
    }
    
то нормально компилится но при нажатии кнопки вываливается и ошибки такие
05-30 07:10:05.798: E/AndroidRuntime(526): FATAL EXCEPTION: main
05-30 07:10:05.798: E/AndroidRuntime(526): java.lang.IllegalStateException: Could not find a method onClickStart(View) in the activity class ru.startandroid.develop.onclick.MainActivity for onClick handler on view class android.widget.Button with id 'btnStart'
05-30 07:10:05.798: E/AndroidRuntime(526): at android.view.View$1.onClick(View.java:3026)
05-30 07:10:05.798: E/AndroidRuntime(526): at android.view.View.performClick(View.java:3480)
05-30 07:10:05.798: E/AndroidRuntime(526): at android.view.View$PerformClick.run(View.java:13983)
05-30 07:10:05.798: E/AndroidRuntime(526): at android.os.Handler.handleCallback(Handler.java:605)
05-30 07:10:05.798: E/AndroidRuntime(526): at android.os.Handler.dispatchMessage(Handler.java:92)
05-30 07:10:05.798: E/AndroidRuntime(526): at android.os.Looper.loop(Looper.java:137)
05-30 07:10:05.798: E/AndroidRuntime(526): at android.app.ActivityThread.main(ActivityThread.java:4340)
05-30 07:10:05.798: E/AndroidRuntime(526): at java.lang.reflect.Method.invokeNative(Native Method)
05-30 07:10:05.798: E/AndroidRuntime(526): at java.lang.reflect.Method.invoke(Method.java:511)
05-30 07:10:05.798: E/AndroidRuntime(526): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-30 07:10:05.798: E/AndroidRuntime(526): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-30 07:10:05.798: E/AndroidRuntime(526): at dalvik.system.NativeStart.main(Native Method)
05-30 07:10:05.798: E/AndroidRuntime(526): Caused by: java.lang.NoSuchMethodException: onClickStart [class android.view.View]
05-30 07:10:05.798: E/AndroidRuntime(526): at java.lang.Class.getConstructorOrMethod(Class.java:460)
05-30 07:10:05.798: E/AndroidRuntime(526): at java.lang.Class.getMethod(Class.java:915)
05-30 07:10:05.798: E/AndroidRuntime(526): at android.view.View$1.onClick(View.java:3019)
05-30 07:10:05.798: E/AndroidRuntime(526): ... 11 more
ну то есть он их в MainActivity не находит.

Собственно вопрос куда надо прописать обработчик чтоб корректно обрабатывал события из fragment_main.

полный код MainActivity.java

Код: Выделить всё

package ru.startandroid.develop.onclick;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

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

        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment())
                    .commit();
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
    	   
    	   TextView tvOut;
    	   Button btnStart;
    	   
        public PlaceholderFragment() { 
        	
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            
           
            
            return rootView;
        }
    
        public void onClickStart(View v) {
        	tvOut.setText("Нажата кнопка start");
          } 
    }
    

}

полный код fragment_main

Код: Выделить всё

<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="ru.startandroid.develop.onclick.MainActivity$PlaceholderFragment" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/tvOut"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="50dp"
            android:text="TextView" />

        <Button
            android:id="@+id/btnStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClickStart"
            android:text="start" />

    </LinearLayout>

</RelativeLayout>


Donart
Сообщения: 114
Зарегистрирован: 06 ноя 2013, 08:59

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Donart » 30 май 2014, 11:03

Хочется чтоб данный метод работал если элементы расположены в fragment_main.
Это все хорошо, но где вы находите элементы view? где (Button) rootView.findViewById(R.id.btnStart) ?
Но при попытки разместить обработчик нажатия в
Java так не умеет, учите язык.

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение klblk » 30 май 2014, 12:21

Donart писал(а):
Хочется чтоб данный метод работал если элементы расположены в fragment_main.
Это все хорошо, но где вы находите элементы view? где (Button) rootView.findViewById(R.id.btnStart) ?
можно в xml у Button прописать "android:onClick="onClickStart"" и тогда при нажатии на эту кнопку будет вызываться эта функция. никаких findViewById и присвоений обработчиков в коде не нужно. (последние строчки данного урока)

shyrick
попробуйте написать метод onClickStart() во фрагменте, а не в активити.
Если не поможет то используйте интерфейс OnClickListener.

shyrick
Сообщения: 5
Зарегистрирован: 28 май 2014, 16:31

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение shyrick » 30 май 2014, 13:04

klblk писал(а):
Donart писал(а): shyrick
попробуйте написать метод onClickStart() во фрагменте, а не в активити.
Если не поможет то используйте интерфейс OnClickListener.
Через OnClickListener у меня такая конструкция получаеться

Код: Выделить всё

 public static class PlaceholderFragment extends Fragment implements OnClickListener {
    	  
    	   TextView tvOut;
    	   Button btnOk;
    	   Button btnCancel;
    	   
        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            
            tvOut = (TextView) rootView.findViewById(R.id.tvOut);
            btnOk = (Button) rootView.findViewById(R.id.btnOk);
            btnCancel = (Button) rootView.findViewById(R.id.btnCancel);
           
            btnOk.setOnClickListener(this);
            btnCancel.setOnClickListener(this);
           
            return rootView;
        }

		@Override
		public void onClick(View v) {
			// по id определеяем кнопку, вызвавшую этот обработчик
		     switch (v.getId()) {
		     case R.id.btnOk:
		       // кнопка ОК
		       tvOut.setText("Нажата кнопка ОК");
		       break;
		     case R.id.btnCancel:
		       // кнопка Cancel
		       tvOut.setText("Нажата кнопка Cancel");
		       break;
		     }
			
		}
или так

Код: Выделить всё

 public static class PlaceholderFragment extends Fragment {
    	
    	TextView tvOut;
    	Button btnOk, btnCancel;

        public PlaceholderFragment() {
        }
        
        
        @Override
        
   	
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
        	
           

            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            
            tvOut = (TextView) rootView.findViewById(R.id.tvOut);
           
            btnOk = (Button) rootView.findViewById(R.id.btnOk);
            
            btnCancel = (Button) rootView.findViewById(R.id.btnCancel);
            
            OnClickListener oclBtn = new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // по id определеяем кнопку, вызвавшую этот обработчик
                    switch (v.getId()) {
                    case R.id.btnOk:
                      // кнопка ОК
                      tvOut.setText("Нажата кнопка ОК");
                      break;
                    case R.id.btnCancel:
                      // кнопка Cancel
                      tvOut.setText("Нажата кнопка Cancel");
                      break;
                    }
                  }
              };
              btnOk.setOnClickListener(oclBtn);
              btnCancel.setOnClickListener(oclBtn);
            return rootView;
            
        }
    }
и все прекрасно работает.

а вот с последним способом не получается при попытки пихнуть в public View onCreateView материться
при выносе сюда public static class PlaceholderFragment extends Fragment

валиться с ошибками при нажатии...

Donart
Сообщения: 114
Зарегистрирован: 06 ноя 2013, 08:59

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Donart » 30 май 2014, 13:12

а вот с последним способом не получается при попытки пихнуть в public View onCreateView материться
Потому что так и не сработает , Fragment так не умеет. Только с OnClickListener.

Viewer
Сообщения: 180
Зарегистрирован: 30 апр 2014, 11:42

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Viewer » 30 май 2014, 18:53

shyrick писал(а):Вопрос возник по третьему методу. Вызов OnClick из xml.

Хочется чтоб данный метод работал если элементы расположены в fragment_main.
Всем View построенным из xml-разметки (впрочем, как и построенным непосредственно в коде) передается контекст Activity, у фрагментов нет своего контекста, поскольку они создаются не системой, а приложением, они используют контекст той Activity которая их создает. Запомните раз и навсегда, фрагмент это не компонент Андроид, это как бы надстройка, дополнение к Activity. Поэтому никакие View и их иерархия непосредственно к ним не привязана, вы думаете, что они находятся во фрагменте, но на самом деле они находятся в Activity, а фрагмент используется только как контейнер и не более того.
В соответствии с вышеизложенным, если смотреть с точки зрения View, то они понятия не имеют, что находятся во фрагменте и ничего не знают о нем, зато они в своем распоряжении имеют контекст Activity, вот через него и работает код, который обрабатывает атрибут onClick, для более пытливых поясню - это делается через отражение (reflection), есть такой механизм в Java. Поэтому View ну никак не сможет найти через отражение ваш метод, если вы его поместите во фрагмент, он будет пытаться найти его только в Activity.

Если вы хотите обрабатывать нажатия кнопок во фрагменте, то только через интерфейсы - Listener-ы и никак иначе.
Как вариант, можно использовать атрибут onClick xml-разметки, но метод обработки размещать в Activity, а во фрагменте сделать такой же метод, который будет вызываться из Activity.
---MyActivity---
...
public void onClick(View v) {
((MyFragment)getFragmentManager().findFragmentByTag("MyFragment_tag")).onClick(v);

}
...

shyrick
Сообщения: 5
Зарегистрирован: 28 май 2014, 16:31

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение shyrick » 02 июн 2014, 10:27

Спасибо за разъяснение.
Попробую построить такую конструкцию но уже сейчас вижу что через Listener-ы код читабельные и понятнее получиться.
Может кто посоветует толковую книжку по жабе чтоб легче было понимать уроки данные. Желательно на русском для первичного ознакомления.

Viewer
Сообщения: 180
Зарегистрирован: 30 апр 2014, 11:42

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение Viewer » 02 июн 2014, 11:01

shyrick писал(а): Может кто посоветует толковую книжку по жабе чтоб легче было понимать уроки данные. Желательно на русском для первичного ознакомления.
viewtopic.php?f=17&t=147

drak
Сообщения: 2
Зарегистрирован: 04 июн 2014, 13:20

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение drak » 12 июн 2014, 16:03

Я новачок ...при запускание програма вилетаєет
Activity
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {


TextView tvOut;
Button btnStart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

}
public void onClick(View v) {
tvOut.setText("nazhata knopka");
}
}



main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal">

<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="30dp"
android:orientation="vertical" >

<TextView
android:id="@+id/tvOut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="50dp"
android:text="TextView" />

<Button
android:id="@+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClickStart"
android:text="start" />

<Button/>

</LinearLayout>

</LinearLayout>
Вложения
Записати.PNG
Записати.PNG (53.88 КБ) 14342 просмотра

Аватара пользователя
klblk
Сообщения: 1097
Зарегистрирован: 18 окт 2012, 11:17
Откуда: г. Красноярск

Re: Урок 10. Оптимизируем реализацию обработчиков.

Сообщение klblk » 13 июн 2014, 05:57

нет у вас функции "onClickStart()"
и TextView tvOut - не определен.
и учитесь оформлять код на форуме

Ответить