Как передать строку из Activity в Fragment

412
11 января 2017, 01:02

Хочу передать строку из Activity в Fragment, помогите исправить ошибку.

Auth.java

public class Auth extends AppCompatActivity {
    private final String TAG = "log_tag";
    private EditText etUser;
    private EditText etPassword;
    private Button btnLogin;
    private Button btnSignUp;
    private Realm realm;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.auth);
        etUser = (EditText) findViewById(R.id.editTextUserName);
        etPassword = (EditText) findViewById(R.id.editTextPassword);
        btnLogin = (Button) findViewById(R.id.btnLogin);
        btnSignUp = (Button) findViewById(R.id.btnSignUp);
        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                authorization(view);
            }
        });
        btnSignUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), SignUp.class);
                startActivity(intent);
            }
        });
    }
    private void authorization(View view) {
        Realm.init(getApplicationContext());
        RealmConfiguration realmConfiguration = new RealmConfiguration
                .Builder()
                .deleteRealmIfMigrationNeeded()
                .build();
        realm = Realm.getInstance(realmConfiguration);
        RealmResults<User> user = realm.where(User.class).findAll();
        for (int i = 0; i < user.size(); i++) {
            if (user.get(i).getUserName().equals(etUser.getText().toString())&&
                    user.get(i).getPassword().equals(etPassword.getText().toString())) {
                Log.d(TAG, "authorization: user size = " + user.size());
                Log.d(TAG, "authorization: userName = " + user.get(i).getUserName());
                Log.d(TAG, "authorization: password = " + user.get(i).getPassword());
                Profile.newInstance(user.get(i).getUserName());
                Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                startActivity(intent);
            } else
                Snackbar.make(view, "Error! Check your entries.", Snackbar.LENGTH_LONG).show();
        }
    }
}

Profile.java

public class Profile extends Fragment {
    private final String TAG = "log_tag";
    private CircleImageView imageView;
    private TextView tvName;
    private TextView tvEmail;
    private TextView tvPhone;
    private Realm realm;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.profile, container, false);
        imageView = (CircleImageView) view.findViewById(R.id.imageViewAvatar);
        tvName = (TextView) view.findViewById(R.id.tvFirstAndLastName);
        tvEmail = (TextView) view.findViewById(R.id.tvEmail);
        tvPhone = (TextView) view.findViewById(R.id.tvPhone);
        writeProfile();
        return view;
    }
    public static Profile newInstance(final String userName) {
        final Profile profile = new Profile();
        final Bundle bundle = new Bundle();
        bundle.putString("userName", userName);
        profile.setArguments(bundle);
        return profile;
    }
    private void writeProfile() {
        Realm.init(getActivity());
        RealmConfiguration realmConfiguration = new RealmConfiguration
                .Builder()
                .deleteRealmIfMigrationNeeded()
                .build();
        realm = Realm.getInstance(realmConfiguration);
        String userName = this.getArguments().getString("userName");//здесь падает ошибка
        Log.d(TAG, "writeProfile: userName = " + userName);
        RealmResults<User> user = realm.where(User.class).findAll();
        User userData = user.where().equalTo("userName", userName).findFirst();
        tvName.setText(userData.getFirstName() + " " + userData.getLastName());
        tvEmail.setText(userData.getEmail());
        tvPhone.setText(userData.getPhone());
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
private Fragment fragment;
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    fragmentManager = getSupportFragmentManager();
    fragment = new Feed();
    final FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.add(R.id.main_container, fragment).commit();
    BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.action_feed:
                    fragment = new Feed();
                    break;
                case R.id.action_my_feed:
                    fragment = new MyFeed();
                    break;
                case R.id.action_profile:
                    fragment = new Profile();
                    break;
            }
            final FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.main_container, fragment).commit();
            return true;
        }
    });
}
}

ну и сама ошибка

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.nikolai.engadgetnews, PID: 8073
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
  at com.example.nikolai.engadgetnews.Profile.Profile.writeProfile(Profile.java:61)
  at com.example.nikolai.engadgetnews.Profile.Profile.onCreateView(Profile.java:40)
  at android.support.v4.app.Fragment.performCreateView(Fragment.java:2184)
  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1298)
  at android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323)
  at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136)
  at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2092)
  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1998)
  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:709)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:148)
  at android.app.ActivityThread.main(ActivityThread.java:5417)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Answer 1

Вам нужна двухходовка.

1 - передать user name в вызываемую MainActivity. Например, добавив этот параметр в intent:

intent = new Intent(....);
intent.putExtra("userName", userName);
startActivity(intent);

2 - в вызванной активити достать этот параметр и передать его во фрагмент, например, так:

            case R.id.action_profile:
                userName = getIntent().getStringExtra("userName");
                fragment = Profile.newInstance(userName);
                break;
Answer 2

Проблема в том, что Вы неправильно используете фрагменты.

В строке:

Profile.newInstance(user.get(i).getUserName());

Вы создаете фрагмент и ничего не делаете с ним. Более того – Вы создаете безымянный объект, который, при случае, будет почищен GC.

Попробуйте вот так:

FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
    fragment = Profile.newInstance(user.get(i).getUserName());
    fm.beginTransaction()
        .add(R.id.fragment_container, fragment)
        .commit();
}

где R.id.fragment_container – контейнер для фрагментов.

В приведенном коде сначала проверяется, находится ли в заданном контейнере фрагмент, если находится, то все ок – ничего делать не нужно, в противном случае создается инстанс фрагмента и добавляется в FragmentManager.

UPD: В обновленном коде Вы создаете инстанс фрагмента без всяких аргументов:

fragment = new Profile();

Поэтому при вызове getArguments() получаете null.

Если в одной ситуации Вам нужно задать и использовать аргументы, а в другой – нет, то во фрагменте просто пропишите:

if (getArguments() != null) {
    //some actions
}

В таком случае, когда аргументы заданы, будут выполняться какие-то действия, а в противном случае – никаких действий выполнено не будет.

Answer 3
            Profile.newInstance(user.get(i).getUserName());
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            startActivity(intent);
  1. Вы получаете фрагмент с переданным ему user name. Его бы передать FragmentManager'у, чтобы показать на экране. Вы же его никуда не деваете, и он (фрагмент) попадает к сборщику мусора.
  2. Вы запускаете MainActivity. Во-первых, про эту MainActivity ничего не известно, и непонятно, какое отношение эта activity имеет к фрагменту Profile. Но точно видно, что MainActivity не получает user name.
READ ALSO
Сортировка чисел и вывод их на экран

Сортировка чисел и вывод их на экран

Я сделал 1 и 2 пунктыКак сделать 3 пункт?

245
Доступ к событиям чужого калентаря

Доступ к событиям чужого калентаря

Необходимо получить список событий чужого Google-календаряПытаюсь сделать так:

152
GridLayout в ScrollView выдает ошибку

GridLayout в ScrollView выдает ошибку

Получил много ошибок, но считаю что основная эта, подскажите пожалуйста, в чем проблема?

148
как спрятать клавиатуру, открытую через showSoftInput

как спрятать клавиатуру, открытую через showSoftInput

в одном из активити открывается клавиатура таким образом:

157