如何通过引用传递对象?

时间:2017-07-05 09:23:37

标签: java android android-intent reference

这是我在这里的第一篇文章,所以要温柔:p 事情就是这样,我面临着一个非常棘手的问题,经过几次研究,我无法找到一个干净的解决方案。让我解释一下:

我实际上正在开发一个用于餐厅管理的Android应用程序。 在活动A中,我能够创建一些具有不同参数的文章(图片,名称,价格......)。 我还可以创建一个菜单,其中我指出包含哪些文章。为此,我运行活动B,其中包含要选择的可用文章(我创建的文章)的动态列表。在拾取其中一些后,自定义选择的对象将通过包裹发送到活动A.所选文章列表在菜单中更新。 但据我所知,这就是使用Parcels创建另一个对象实例的事情。因此,如果我修改或删除文章,菜单中包含的文章列表不会改变,显然我希望菜单中的列表自动更新。

有没有办法通过引用简单地通过活动传递自定义对象? 什么可以是一个干净的解决方案,使菜单中的文章列表动态?

以下是一些代码:

在活动A中,在菜单界面中单击+按钮添加一篇文章,该文章运行活动B(附加内容是之前已包含在菜单中的文章列表,因此在开头它是空的)。

//Add article
    FloatingActionButton addArticleButton = (FloatingActionButton)parentActivity.findViewById(R.id.addArticleButton);
    addArticleButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showMenuDetails(menuListView,menuAdapter,currentMenu);
            parentActivity.startActivityForResult(new Intent(parentActivity.getApplicationContext(),ChooseArticleActivity.class).putParcelableArrayListExtra("menuArticleList",currentMenu.getArticles()),PICK_ARTICLES);
        }
    });

在活动B中:我在可用文章列表中选择文章(我创建的文章)。拿起后,按OK按钮将所选文章的列表放在结果Intent中作为Parcelable Extras

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.choose_article_layout);
    initializeLists();

    this.resultIntent = new Intent();
}

private void initializeLists(){
    final ListView articleToChoose = (ListView)findViewById(R.id.articleToChoose);
    final ListView articleChosen = (ListView)findViewById(R.id.articleChosen);

    final ArrayList<Article> articleToChooseList = (ArrayList<Article>)MainActivity.model.getArticleList().getArticleList().clone();
    final ArrayList<Parcelable> articleChosenListParcelable = (ArrayList<Parcelable>)this.getIntent().getParcelableArrayListExtra("menuArticleList");
    final ArticleAdapter articleToChooseAdapter = new ArticleAdapter(getApplicationContext(), articleToChooseList);
    articleToChoose.setAdapter(articleToChooseAdapter);


    ArrayList<Article> articleChosenListTemp = new ArrayList<>();
    ArrayList<Article> articleToRemove = new ArrayList<>();
    for(Parcelable a:articleChosenListParcelable){
        articleChosenListTemp.add((Article)a);
        for(Article article:articleToChooseList){
            if(article.getName().equals(((Article) a).getName())){
                articleToRemove.add(article);
            }
        }
    }
    articleToChooseList.removeAll(articleToRemove);
    articleToChooseAdapter.notifyDataSetChanged();

    final ArrayList<Article> articleChosenList = articleChosenListTemp;

    final ArticleAdapter articleChosenAdapter = new ArticleAdapter(getApplicationContext(),articleChosenList);


    articleChosen.setAdapter(articleChosenAdapter);

    articleChosen.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Article articleClicked = articleChosenAdapter.getItem(position);
            articleChosenList.remove(articleClicked);
            articleToChooseList.add(articleClicked);
            articleChosenAdapter.notifyDataSetChanged();
            articleToChooseAdapter.notifyDataSetChanged();
        }
    });

    articleToChoose.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Article articleClicked = articleToChooseAdapter.getItem(position);
            if(!articleChosenList.contains(articleClicked)){
                articleChosenList.add(articleClicked);
                articleToChooseList.remove(articleClicked);
                articleToChooseAdapter.notifyDataSetChanged();
                articleChosenAdapter.notifyDataSetChanged();
            }
        }
    });



    Button okButton = (Button)findViewById(R.id.okButton);
    okButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            chosenArticleListAttr = articleChosenList;
            resultIntent.putParcelableArrayListExtra("articleList",chosenArticleListAttr);
            setResult(RESULT_OK,resultIntent);
            finish();
        }
    });

    Button cancelButton = (Button)findViewById(R.id.cancelButton);
    cancelButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });
}

在活动A中,在onActivityResult中我捕获结果并更新列表,但这里添加的文章与模型中的文章列表不是同一个实例

if(requestCode==PICK_ARTICLES && resultCode==RESULT_OK){
        ArticleAdapter articleAdapter = (ArticleAdapter) gestionMenusLayout.getMenuArticleListView().getAdapter();

        ArrayList<Parcelable> chosenArticleList = (ArrayList<Parcelable>)data.getParcelableArrayListExtra("articleList");
        gestionMenusLayout.getCurrentMenu().getArticles().clear();
        for(Parcelable a:chosenArticleList){
            gestionMenusLayout.getCurrentMenu().addArticle((Article)a);
        }
        articleAdapter.notifyDataSetChanged();
    }

2 个答案:

答案 0 :(得分:0)

仅出于调试目的,我建议您使用public static List<Article> articleList并直接从活动A或B中调用

更好但更省力的解决方案是将列表存储在数据库中,并且每个更新,查询......都通过它来进行。您可以使用服务器的数据库(人们通常从中获取文章)或离线数据库,如Realm here

答案 1 :(得分:0)

我终于找到了一个非常简单易用的解决方案。

我不断通过包裹传递我的文章对象。 但是当它创建一个新实例时,我不是添加这个实例,而是在相等键检查(文章名称)之后添加原始实例(模型中的那个)。通过这样做,我保留了我的文章的参考。

感谢您的帮助!

编辑: 这是代码:

if(requestCode==PICK_ARTICLES && resultCode==RESULT_OK){
        ArticleAdapter articleAdapter = (ArticleAdapter) gestionMenusLayout.getMenuArticleListView().getAdapter();

        ArrayList<Parcelable> chosenArticleList = (ArrayList<Parcelable>)data.getParcelableArrayListExtra("articleList");
        gestionMenusLayout.getCurrentMenu().getArticles().clear();
        ArrayList<Article> modelArticles = MainActivity.model.getArticleList().getArticleList();
        for(Parcelable a:chosenArticleList){
            for(Article modelArticle:modelArticles){
                if(((Article)a).getName().equals(modelArticle.getName())){
                    gestionMenusLayout.getCurrentMenu().addArticle(modelArticle);
                }
            }
        }
        articleAdapter.notifyDataSetChanged();
    }