改变一个ListView项目从另一个片段 [英] change the items in a ListView from another fragment

查看:188
本文介绍了改变一个ListView项目从另一个片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个片段,让我们给他们打电话片段A和片段B,这是一个NavigationDrawer的一部分(这是他们的活动绑定到)。在片段A我有一个按钮。当此按钮pressed,我想另一个项目添加到片段B ListView中。

I have two fragments, lets call them Fragment A and Fragment B, which are a part of a NavigationDrawer (this is the activity they a bound to). In Fragment A I have a button. When this button is pressed, I would like another item added to the ListView in Fragment B.

什么是做到这一点的最好方法是什么?使用意图,保存preferences,使一些公共(?)或其他什么东西?

What is the best way to do this? Use Intents, SavedPreferences, making something public(?) or something else?

编辑5:20/7/13这是srains最新code

EDIT 5: 20/7/13 This is with srains latest code

这是 NavigationDrawer ,我用它来启动片段:

This is the NavigationDrawer that I use to start the fragments:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class Navigation_Drawer extends FragmentActivity {

    public DrawerLayout mDrawerLayout; // Creates a DrawerLayout called_.
    public ListView mDrawerList;
    public ActionBarDrawerToggle mDrawerToggle;

    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    private String[] mNoterActivities; // This creates a string array called _.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub

// Just setting up the navigation drawer

    } // End of onCreate

// Removed the menu


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

    private void selectItem(int position) { 

        FragmentManager fragmentManager = getSupportFragmentManager();

        if (position == 0) {
            Fragment qnfragment = new QuickNoteFragment(); 
            ((FragmentBase) qnfragment).setContext(this);
            Bundle args = new Bundle(); // Creates a bundle called args
            args.putInt(QuickNoteFragment.ARG_nOTERACTIVITY_NUMBER, position); 

            qnfragment.setArguments(args);

            fragmentManager.beginTransaction()
                    .replace(R.id.content_frame, qnfragment).commit();



        } else if (position == 3) {
            Fragment pendViewPager = new PendViewPager(); // This is a ViewPager that includes HistoryFragment
            ((FragmentBase) pendViewPager).setContext(this);
            Bundle args = new Bundle();

            pendViewPager.setArguments(args);
            fragmentManager.beginTransaction()
                    .replace(R.id.content_frame, pendViewPager).commit();
        }

    // Update title etc
    }


    @Override
    protected void onPostCreate(Bundle savedInstanceState) { // Used for the NavDrawer toggle
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) { // Used for the NavDrawer toggle
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggles
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

}

这是QuickNoteFragment:

This is QuickNoteFragment:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class QuickNoteFragment extends FragmentBase implements OnClickListener {

    public static final String ARG_nOTERACTIVITY_NUMBER = "noter_activity";

    Button b_create;
// removed other defining stuff

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.quicknote, container, false);
        int i = getArguments().getInt(ARG_nOTERACTIVITY_NUMBER);
        String noter_activity = getResources().getStringArray(
                R.array.noter_array)[i];
        FragmentManager fm = getFragmentManager();
        setRetainInstance(true);

        b_create = (Button) rootView.findViewById(R.id.qn_b_create);

        // Removed other stuff

        getActivity().setTitle(noter_activity);
        return rootView;
    }

    @Override
    public void onClick(View v) {

        // TODO Auto-generated method stub

        switch (v.getId()) {

        case R.id.qn_b_create:

                              String data = "String data";
                DataModel.getInstance().addItem(data);

            break;
        }
    }

@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // TODO Auto-generated method stub
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection

        }
    }

    public interface OnItemAddedHandler { // Srains code
        public void onItemAdded(Object data);
    }
}

这是HistoryFragment(记住它的一部分 ViewPager

This is HistoryFragment (Remember it is part of a ViewPager):

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.RiThBo.noter.QuickNoteFragment.OnItemAddedHandler;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class HistoryFragment extends FragmentBase implements OnItemAddedHandler {

    ListView lv;
    List<Map<String, String>> planetsList = new ArrayList<Map<String, String>>();
    SimpleAdapter simpleAdpt;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View view = inflater.inflate(R.layout.history, container, false);
        initList();


        ListView lv = (ListView) view.findViewById(R.id.listView);
        simpleAdpt = new SimpleAdapter(getActivity(), planetsList,
                android.R.layout.simple_list_item_1, new String[] { "planet" },
                new int[] { android.R.id.text1 });

        lv.setAdapter(simpleAdpt);

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

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

                // We know the View is a TextView so we can cast it

                TextView clickedView = (TextView) view;

                Toast.makeText(
                        getActivity(),
                        "Item with id [" + id + "]  - Position [" + position
                                + "] - Planet [" + clickedView.getText() + "]",
                        Toast.LENGTH_SHORT).show();
            }

        });
        registerForContextMenu(lv);

        return view;

    }

    private void initList() {

        // We populate the planets

        planetsList.add(createPlanet("planet", "Mercury"));
        planetsList.add(createPlanet("planet", "Venus"));
        planetsList.add(createPlanet("planet", "Mars"));
        planetsList.add(createPlanet("planet", "Jupiter"));
        planetsList.add(createPlanet("planet", "Saturn"));
        planetsList.add(createPlanet("planet", "Uranus"));
        planetsList.add(createPlanet("planet", "Neptune"));

    }

    private HashMap<String, String> createPlanet(String key, String name) {

        HashMap<String, String> planet = new HashMap<String, String>();

        planet.put(key, name);

        return planet;

    }

    // We want to create a context Menu when the user long click on an item

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,

    ContextMenuInfo menuInfo) {

        super.onCreateContextMenu(menu, v, menuInfo);

        AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;

        // We know that each row in the adapter is a Map

        HashMap map = (HashMap) simpleAdpt.getItem(aInfo.position);

        menu.setHeaderTitle("Options for " + map.get("planet"));
        menu.add(1, 1, 1, "Details");
        menu.add(1, 2, 2, "Delete");

    }
     @Override
      public void onItemAdded(Object data) {
          // to add item
          String string = String.valueOf(data);
          Toast.makeText(getContext(), "Data: " + string, Toast.LENGTH_SHORT).show();
          planetsList.add(createPlanet("planet", string));
      }
      @Override
    public void onStart() {
          super.onStart();

          DataModel.getInstance().setOnItemAddedHandler(this);
      }
}

这是FragmentBase:

This is FragmentBase:

   import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;

      public class FragmentBase extends Fragment {

            private FragmentActivity mActivity; // I changed it to FragmentActivity because Activity was not working, and my `NavDrawer` is a FragmentActivity.

            public void setContext(FragmentActivity activity) {
                mActivity = mActivity;
            }

            public FragmentActivity getContext() {
                return mActivity;
            }
    }

这是DataModel的:

This is DataModel:

  import android.util.Log;
    import com.xxx.xxx.QuickNoteFragment.OnItemAddedHandler;

public class DataModel {

    private static DataModel instance;
    private static OnItemAddedHandler mOnItemAddHandler;

    public static DataModel getInstance() {
        if (null == instance) {
            instance = new DataModel();
        }
        return instance;
    }

    public void setOnItemAddedHandler(OnItemAddedHandler handler) {
        mOnItemAddHandler = handler;
    }

    public void addItem(Object data) {
        if (null != mOnItemAddHandler)
            mOnItemAddHandler.onItemAdded(data);
        else {
            Log.i("is context null?", "yes!");
        }  
    }
}

感谢您

推荐答案

我建议你使用接口 MVC ,这将使你的code更容易维护。

I suggest you to use interface and MVC, that will make your code much more maintainable.

首先,你需要一个接口:

First you need an interface:

    public interface OnItemAddedHandler {
        public void onItemAdded(Object data);
    }

然后,你将需要一个数据模型:

Then, you will need a data model:

    public class DataModel {

        private static DataModel instance;
        private static OnItemAddedHandler mOnItemAddHandler;

        public static DataModel getInstance() {
            if (null == instance) {
                instance = new DataModel();
            }
            return instance;
        }

        public void setOnItemAddedHandler(OnItemAddedHandler handler) {
            mOnItemAddHandler = handler;
        }

        public void addItem(Object data) {
            if (null != mOnItemAddHandler)
                mOnItemAddHandler.onItemAdded(data);
        }
    }

当您单击该按钮,可以添加数据到数据模型:

When you click the button, you can add data into the datamodel:

    Object data = null;
    DataModel.getInstance().addItem(data);

然后, FragmentB 实现接口 OnItemAddedHandler 添加项目

    public class FragmentB implements OnItemAddedHandler {

        @Override
        public void onItemAdded(Object data) {
            // to add item
        }
    }

此外,当 FragmentB 开始,你应该自己注册的DataModel:

also, When the FragmentB start, you should register itself to DataModel:

    public class FragmentB implements OnItemAddedHandler {

        @Override
        public void onItemAdded(Object data) {
            // to add item
        }

        @Override
        protected void onStart() {
            super.onStart();

            DataModel.getInstance().setOnItemAddedHandler(this);
        }
    }

您还可以添加 DataModel.getInstance()setOnItemAddedHandler(本); 来的的onCreate 方法 FragmentB

You also can add DataModel.getInstance().setOnItemAddedHandler(this); to the onCreate method of FragmentB

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    DataModel.getInstance().setOnItemAddedHandler(this);

    // do other things
}

更新

您可以简单地发送字符串:

you can send string simply:

    String data = "some string";
    DataModel.getInstance().addItem(data);

然后在 FragementB

    public class FragmentB implements OnItemAddedHandler {

        @Override
        public void onItemAdded(Object data) {
            // get what you send into method DataModel.getInstance().addItem(data);
            String string = String.valueOf(data);
        }
    }

更新

确定。你必须添加 DataModel.getInstance()。setOnItemAddedHandler(本) onCreateView 方法,所以没有必要加它在onStart()方法。您可以删除整个在onStart 方法。

OK. You have add DataModel.getInstance().setOnItemAddedHandler(this) in onCreateView method, so there is no need to add it in onStart() method. You can remove the whole onStart method.

在onStart 将在片段开始叫,我们并不需要把它调用 onCreateView 。和 onItemAdded 将调用调用方法时, DataModel.getInstance()的addItem(数据),我们不需要调用它 onCreateView 没有。​​

onStart will be called on the fragment start, we do not need to call it in onCreateView. And on onItemAdded will be call when call the method DataModel.getInstance().addItem(data), we do not need to call it in onCreateView neither.

所以,你可以从 onCreateView 删除低于code方法:

so, you can remove the code below from onCreateView method:

   DataModel.getInstance().setOnItemAddedHandler(this);
   // remove the methods below
   // onItemAdded(getView());
   // onStart();

您有另一个片段,其中有一个按钮,就可以在clickHandler函数添加codeS如下:

You have another fragment where there is a button, you can add the codes below in the clickhandler function:

String data = "some string";
DataModel.getInstance().addItem(data);

UPDATE3

我觉得 HistoryFragment 后已经脱离时, QuickNoteFragment
您可以添加code到 HistoryFragment 查询:

I think the HistoryFragment has been detached after you when to QuickNoteFragment You can add code to HistoryFragment to check:

@Override
public void onDetach() {
    super.onDetach();
    Log.i("test", String.format("onDetach! %s", getActivity() == null));
}

UPDATE4

我觉得 HistoryFragment QuickNoteFragment 应该有一个父类,命名为 FragmentBase

I think HistoryFragment and QuickNoteFragment should has an parent class, named FragmentBase:

    public class FragmentBase extends Fragment {

        private Activity mActivity;

        public void setContext(Activity activity) {
            mActivity = mActivity;
        }

        public Activity getContext() {
            return mActivity;
        }
    }

HistoryFragment QuickNoteFragment 扩展 FragmentBase 。然后,当你在它们之间切换,可以调用 setContext 来设置一个活动,如:

HistoryFragment and QuickNoteFragment extends FragmentBase. Then when you switch between them, you can call setContext to set a Activity, like:

private void selectItem(int position) {

    FragmentManager fragmentManager = getSupportFragmentManager();

    if (position == 0) {
        Fragment qnfragment = new QuickNoteFragment();
        qnfragment.setContext(this);

        // ...

    } else if (position == 1) {
        Fragment pagerFragment = new RemViewPager();
        pagerFragment.setContext(this);

        // ...
    }
}

现在,我们可以通过调用的getContext 获得 HistoryFragment 一个非空的活动,所以我们可以改变 onItemAdded 方法:

now, we can get a non-null activity in HistoryFragment by calling getContext, so we can change onItemAdded method to:

  @Override
  public void onItemAdded(Object data) {
      // to add item
      String string = String.valueOf(data);
      Toast.makeText(getContext(), "Data: " + string, Toast.LENGTH_SHORT).show();
      planetsList.add(createPlanet("planet", string));
  }

我希望这是可行的。

I hope this would work.

这篇关于改变一个ListView项目从另一个片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆