片段 - 如何将它们用于需要操作的活动?

时间:2015-02-20 09:25:38

标签: android android-intent android-fragments navigation navigation-drawer

首先 - 为新手问题道歉。

我正在尝试实现将在我的应用中使用的导航抽屉。首先,我已经按照Android教程创建了一个基本导航,它改变了片段。

我可以将framelayout id和fragment传递给FragmentTransaction。它很棒。

我决定使用默认的android文件创建一个新的登录活动(在Android Studio中:转到新的 - 活动 - 登录活动)。这让我很困惑。我的问题是:

  1. 我可以创建登录活动的片段,其中LoginActivity中的操作将起作用吗?看起来片段会根据传递的布局创建一个视图,但LoginActivity中使用的方法不起作用?

  2. 如果创建片段对登录活动不起作用,那么在切换活动时确保导航工作的最简洁方法是什么?导航抽屉仅适用于主要活动;切换到其他活动(通过Intent)会导致应用程序丢失导航抽屉操作。操作栏/导航抽屉的图像仍然存在。

  3. 这是我在MainActivity中的一些代码......也许我错过了一些导致导航抽屉在通过Intent切换活动时停止运行的东西?

    (注意:LoginActivity扩展了LoginActivity类中的MainActivity)

    提前感谢任何方向/建议!

    public class MainActivity extends ActionBarActivity {
    
    private NavigationDrawerFragment mNavigationDrawerFragment;
    
    //USER DATA
    public String mUserID;
    public String mToken;
    public String mProgramData;
    
    //NAVIGATION DRAWER
    private CharSequence mTitle;
    private CharSequence mDrawerTitle;
    private String[] mTitles;
    
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarDrawerToggle mActionBarDrawerToggle;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mTitle = mDrawerTitle = getTitle();
    
        // get list items for nav
        mTitles = getResources().getStringArray(R.array.nav_menu);
    
        //drawer widget
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    
        //listview of left drawer
        mDrawerList = (ListView) findViewById(R.id.left_drawer);
    
        // Set up the drawer.
        mDrawerList.setAdapter(new ArrayAdapter<>(this,
                R.layout.drawer_list_item, mTitles));
    
        //set onclicklistener on the each list item of menu options
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
    
        // some styling...
        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
    
        //enables action bar app behavior
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    
        // ties drawerlayout and actionbar for navigation drawers
        mActionBarDrawerToggle = new ActionBarDrawerToggle(
                this,
                mDrawerLayout,
                R.string.navigation_drawer_open,
                R.string.navigation_drawer_close) {
    
            // different titles for the drawer actions
            public void onDrawerClosed(View drawerView) {
                getSupportActionBar().setTitle(mTitle);
            }
    
            public void onDrawerOpened(View drawerView) {
                getSupportActionBar().setTitle(mDrawerTitle);
            }
    
        };
    
        // set drawer toggle as the drawer listener
        mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);
    }
    
     private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id){
            selectItem(position);
        }
    }
    
    @Override
    protected void onPostCreate(Bundle savedInstanceState){
        super.onPostCreate(savedInstanceState);
        mActionBarDrawerToggle.syncState();
    }
    
    @Override
    public void onConfigurationChanged(Configuration newConfig){
       super.onConfigurationChanged(newConfig);
       mActionBarDrawerToggle.onConfigurationChanged(newConfig);
    }
    
        @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 (mActionBarDrawerToggle.onOptionsItemSelected(item)) {
    
            return true;
        }
    
        switch(id) {
            case R.id.action_home:
                Intent home = new Intent(this, MainActivity.class);
                this.startActivity(home);
                break;
            case R.id.action_login:
                Intent login = new Intent(this, LoginActivity.class);
                this.startActivity(login);
                break;
        }
        return super.onOptionsItemSelected(item);
    }
    

    修改

    感谢您帮助我解决我的问题。 不幸的是,我不认为我问的是正确的问题,但是从Android Studio查看LoginActivity代码可能会有所帮助。

    这是 LoginActivity

    的一部分
    public class LoginActivity extends MainActivity implements     LoaderCallbacks<Cursor> {
    
    private UserLoginTask mAuthTask = null;
    
    // UI references.
    private AutoCompleteTextView mUserIDView;
    private EditText mPasswordView;
    private View mProgressView;
    private View mLoginFormView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_login);
    
            // Set up the login form.
            mUserIDView = (AutoCompleteTextView) findViewById(R.id.email);
            populateAutoComplete();
    
            mPasswordView = (EditText) findViewById(R.id.password);
            mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                @Override
                public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
                    if (id == R.id.login || id == EditorInfo.IME_NULL) {
                        attemptLogin();
                        return true;
                    }
                    return false;
                }
            });
    
            Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
            mEmailSignInButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    attemptLogin();
                }
            });
    
            mLoginFormView = findViewById(R.id.login_form);
            mProgressView = findViewById(R.id.login_progress);
        }
    
    
    
    private void populateAutoComplete() {
        getLoaderManager().initLoader(0, null, this);
    }
    
    
    /**
     * Attempts to sign in or register the account specified by the login form.
     * If there are form errors (invalid email, missing fields, etc.), the
     * errors are presented and no actual login attempt is made.
     */
    public void attemptLogin() {
        if (mAuthTask != null) {
            return;
        }
    
        // Reset errors.
        mUserIDView.setError(null);
        mPasswordView.setError(null);
    
        // Store values at the time of the login attempt.
        String email = mUserIDView.getText().toString();
        String password = mPasswordView.getText().toString();
    
        boolean cancel = false;
        View focusView = null;
    
    
        // Check for a valid password, if the user entered one.
        if (TextUtils.isEmpty(password)) {
            mPasswordView.setError(getString(R.string.error_invalid_password));
            focusView = mPasswordView;
            cancel = true;
        }
    
        // Check for a valid email address or ID.
        if (TextUtils.isEmpty(email)) {
            mUserIDView.setError(getString(R.string.error_field_required));
            focusView = mUserIDView;
            cancel = true;
        } else if (!isEmailValid(email) && !isIDValid(email)) {
            mUserIDView.setError(getString(R.string.error_invalid_email));
            focusView = mUserIDView;
            cancel = true;
        }
    
        if (cancel) {
            // There was an error; don't attempt login and focus the first
            // form field with an error.
            focusView.requestFocus();
        } else {
            // Show a progress spinner, and kick off a background task to
            // perform the user login attempt.
            showProgress(true);
            mAuthTask = new UserLoginTask(email, password);
            mAuthTask.execute((Void) null);
        }
    }
    
    private boolean isEmailValid(String email) {
        //TODO: Replace this with your own logic
        return email.contains("@");
    }
    
    private boolean isIDValid(String email) {
        //TODO: Replace this with your own logic
        return email.length() == 6;
    }
    [continued]...........
    

    我将创建一个名为 menu1_Fragment 的LoginActivity的简单片段:

    public class menu1_Fragment extends android.support.v4.app.Fragment {
    View rootview;
    
    public View onCreateView(LayoutInflater inflater, ViewGroup view, Bundle savedInstanceState) {
    
        rootview = (ViewGroup)inflater.inflate(R.layout.activity_login, null);
        return rootview;
    }
    
    
    }
    

    如果我是正确的(希望我错了!)片段被替换为View( menu1_Fragment )。 View无法执行操作(例如单击登录按钮发送httppost请求)。

    另外,你能解释为什么 MainActivity 中的onOptionsItemSelected打破了导航器(抽屉变得不可点击。也无法向右滑动以将其拉起来)。 Intent启动一个活动(LoginActivity),但只显示外观中的抽屉。

2 个答案:

答案 0 :(得分:1)

隐藏您可以执行的ActionBar图标:

 @Override
public boolean onOptionsItemSelected(MenuItem item) {
    // toggle nav drawer on selecting action bar app icon/title
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action bar actions click
    switch (item.getItemId()) {
        case R.id.action_settings:
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}
当您点击replace中的某个项目时,

fragmentdrawable menu list我看到您使用了selectItem(position)方法,但该方法永远不会在您的代码中声明。要做到这一点,你也可以这样做:

private void selectItem(int position){
    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
        case 1:
            fragment = new TestFragment();
            break;
        case 2:
            fragment = new TestFragment2();
            break;
        default:
            break;
    }

    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();

        // update selected item and title, then close the drawer
        setTitle(navMenuTitles[position]);
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        mDrawerLayout.closeDrawer(mDrawerList);
    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }
}

答案 1 :(得分:0)

我给你举个例子,将多个活动定义为片段并使用MainActivity调用,希望你能在其中找到解决方案..

MainActivity.java

package com.example.fragmentdemo1;

import java.util.ArrayList;

import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity implements
        OnItemClickListener {

    MainActivity activity;
    private ListView lv;
    private ArrayList<String> list = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        activity = this;
        lv = (ListView) findViewById(R.id.listView);
        list.add("First");
        list.add("Second");
        list.add("Third");
        list.add("Forth");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity,
                android.R.layout.simple_list_item_1, list);
        lv.setAdapter(adapter);

        lv.setOnItemClickListener(this);

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {

        switch (position) {
        case 0:
            Fragment1 f1 = new Fragment1();
            FragmentTransaction transaction = getSupportFragmentManager()
                    .beginTransaction();
            transaction.addToBackStack(null);
            transaction.replace(R.id.container, f1).commit();
            break;
        case 1:
            Fragment2 f2 = new Fragment2();
            FragmentTransaction transaction2 = getSupportFragmentManager()
                    .beginTransaction();
            transaction2.addToBackStack(null);
            transaction2.replace(R.id.container, f2).commit();

            break;
        case 2:
            Toast.makeText(activity, "" + position, 1000).show();
            Fragment3 f3 = new Fragment3();
            FragmentTransaction transaction3 = getSupportFragmentManager()
                    .beginTransaction();
            transaction3.addToBackStack(null);
            transaction3.replace(R.id.container, f3).commit();
            break;
        case 3:
            Fragment4 f4 = new Fragment4();
            FragmentTransaction transaction4 = getSupportFragmentManager()
                    .beginTransaction();
            transaction4.addToBackStack(null);
            transaction4.replace(R.id.container, f4).commit();
            break;
        default:
            break;
        }

    }

    @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();
        switch (id) {
        case android.R.id.home:

            finish();
            break;

        default:
            break;
        }

        return false;
    }

}

Fragment1.java

package com.example.fragmentdemo1;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


public class Fragment1 extends android.support.v4.app.Fragment{

    TextView tv;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup view,
            Bundle savedInstanceState) {
        tv =(TextView)view.findViewById(R.id.textView1);
        view = (ViewGroup) inflater.inflate(R.layout.fragment1, null);
        return view;
    }
}

Fragment2.java

package com.example.fragmentdemo1;

    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;

    public class Fragment2 extends Fragment {

        TextView tv;
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup view,
                Bundle savedInstanceState) {
            tv =(TextView)view.findViewById(R.id.textView2);
            view = (ViewGroup) inflater.inflate(R.layout.fragment2, null);
            return view;
        }
    }

Fragment3.java

package com.example.fragmentdemo1;

    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;

    public class Fragment3 extends Fragment {
        TextView tv;
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup view,
                Bundle savedInstanceState) {

            tv =(TextView)view.findViewById(R.id.textView3);
            view =(ViewGroup)inflater.inflate(R.layout.fragment3, null);
            return view;
        }
    }

Fragment4.java

package com.example.fragmentdemo1;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class Fragment4 extends Fragment{

    TextView tv;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup view,
            Bundle savedInstanceState) {
        tv =(TextView)view.findViewById(R.id.textView4);

        view = (ViewGroup)inflater.inflate(R.layout.fragment4, null);
        return view;
    }
}

注意:如果要将Fragment类中的方法用于MainActivity,则可以将其设为public static,并且可以使用该方法直接使用该方法,例如Fragment1.countData()

此演示也适用于导航抽屉。