将值从一项活动更新到另一项活动

Posted

技术标签:

【中文标题】将值从一项活动更新到另一项活动【英文标题】:Update values from one activity to another 【发布时间】:2016-02-03 16:39:50 【问题描述】:

我有一个包含列表的活动(类似于 fb 或 instagram 提要),我有喜欢该项目的按钮,它还显示喜欢的数量。现在假设我单击图像,它会在一个单独的活动中打开图像的分解视图,该活动也有类似按钮。如果我在分解视图活动中的图像上点赞,我想在上一个(提要)屏幕中的图像上反映相同的内容。我知道一种方法是在第一个活动的onResume() 方法上从后端刷新提要。但我不想仅仅为了反映 UI 和一些变量的变化而刷新整个页面,失去可能的滚动并破坏用户体验。有没有做这些事情的标准方法? facebook 或其他类似的应用程序是如何实现这一点的?如果有任何图书馆可以提供帮助,也请告诉我。谢谢。

【问题讨论】:

只有将数据更新到数据库中,您才能获得准确的值。如果您想离线进行,则必须将数据保存在任何本地资源中。 我不想维护数据库。实际上我正在创建的应用程序是一种社交应用程序,我无法下载整个图表并将其保存到数据库。没有任何技巧或方法可以让我实现这一目标吗? 【参考方案1】:

我对ActivityResult() + notifyDataSetChanges() 的决定我的代码 10 分钟并不完美,但是:

     public class MainActivity extends Activity 

        private AdapterListView adapterListView;
        private int adapterUpdateItemPosition;
        @Override
        protected void onCreate(Bundle savedInstanceState) 
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_activity);
            ListView listView = (ListView) findViewById(R.id.listView);
            ArrayList<SomeObject> list = new ArrayList<>();
            for (int i = 0 ; i < 20 ; i++ )
                list.add(new SomeObject());
            adapterListView = new AdapterListView( (LayoutInflater) getApplicationContext()
                    .getSystemService(getApplicationContext().LAYOUT_INFLATER_SERVICE), list);
            listView.setAdapter(adapterListView);
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
                    adapterUpdateItemPosition = position;
                    startActivityForResult(new Intent(MainActivity.this, SecondActivity.class), SecondActivity.REQUEST_UPDATE);
                
            );
        



        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) 
            super.onActivityResult(requestCode, resultCode, data);
            if(resultCode == RESULT_OK)
                if (requestCode == SecondActivity.REQUEST_UPDATE)
                    adapterListView.updateListView(adapterUpdateItemPosition, data.getBooleanExtra(SecondActivity.ADAPTER_POSITION, false));
                
            
        
    

public class SecondActivity extends Activity 
    public static final String ADAPTER_POSITION = "ADAPTER_POSITION";
    public static final int REQUEST_UPDATE = 2321;

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

        findViewById(R.id.tv_item_grid).setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                setResult(RESULT_OK, new Intent().putExtra(ADAPTER_POSITION, true));
                finish();
            
        );
    


public class AdapterListView extends BaseAdapter 

    private LayoutInflater lInflater;
    private ArrayList<SomeObject> objects;

    public AdapterListView(LayoutInflater lInflater, ArrayList<SomeObject> objects) 
        this.lInflater = lInflater;
        this.objects = objects;
    


    @Override
    public int getCount() 
        return objects.size();
    

    @Override
    public SomeObject getItem(int position) 
        return objects.get(position);
    

    @Override
    public long getItemId(int position) 
        return position;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        View view = convertView;
        if (view == null) 
            view = lInflater.inflate(R.layout.item_grid, parent, false);
        
        SomeObject p = getItem(position);
        if(p.isLike()) 
            ((TextView) view.findViewById(R.id.tv_item_grid)).setText("LIKE");
         else  ((TextView) view.findViewById(R.id.tv_item_grid)).setText("NOT LIKE");

        return view;
    

    public void updateListView(int position, boolean isLike)
        getItem(position).setLike(isLike);
        notifyDataSetChanged();
    


public class SomeObject
    private boolean like = false;

    public boolean isLike() 
        return like;
    

    public void setLike(boolean like) 
        this.like = like;
    



【讨论】:

【参考方案2】:

只需刷新列表视图适配器提供的下载数据即可。

然后在适配器上调用 notifyDataSetChanged()。

这样您就可以在本地更新数据并刷新您的列表。

不可能只更新列表视图的一行,这是您要找的吗?

【讨论】:

我不明白你写了什么。你能澄清一下吗? 重新下载数据和刷新列表以显示更改之间存在差异。只是将您指向第二件事并询问您是否正在寻找仅更新一行而不是整个列表视图的替代方法。 我只想更新一行,而不是整个列表。假设我重新下载数据,我在特定索引处替换列表对象,并调用 notifyDataSetChanged(),但同样,重新下载数据需要几秒钟,并且更改不会立即发生。 据我所知,没有办法更新单行,如果您要重新下载数据,更新单个项目或整个数组都没有关系,这是我想到的唯一方法是更新数组并等待listview在用户滚动事件上重绘行。【参考方案3】:

您可以使用 LocalBroadcastManager 发送您之前的活动将收听的广播。

Intent intent = new Intent(LIST_UPDATED);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);

【讨论】:

我猜,这只会告诉第一个(提要)活动列表是否需要更新。如何将更改变量的值实际转移到 Feed 活动中? 如果先前的活动被破坏,广播将被浪费。而且这不是正确的方法。 在广播的意图中,您可以设置任何可打包的数据。【参考方案4】:

也许你可以使用startActivityForResult()onActivityResult()

这样你就可以设置一个代码,暗示用户在第二个活动中做了一些需要第一个刷新数据的活动。

【讨论】:

即使我这样做了,我如何实际更新该特定列表索引中的特定变量?以及如何将更改后的值从爆炸屏幕传达给提要屏幕,因为我没有使用意图来启动活动(提要),我只是从后台堆栈关闭顶部活动。 您可以通过intent extras将行对象模型传递到爆炸屏幕,然后,如果您对其进行修改,更改是否会反映在java通过引用传递对象的原始对象上还是我错了吗? 实际上Java通过传递引用的副本来传递对象。我不确定 Nanoc 的建议是否有效。我认为android会复制意图中的对象,因此接收到的对象中的更改不会在原始对象中可见。无论如何,您可以尝试并确认

以上是关于将值从一项活动更新到另一项活动的主要内容,如果未能解决你的问题,请参考以下文章

如何将当前位置从一项活动发送到另一项活动?

无法将位置从一项活动返回到另一项活动

如何将字符串从一项活动发送到另一项活动?

Postgres 创建触发器函数以在允许插入之前将值从一列复制到另一列

如何将值从一个活动中的片段传递到另一个活动? [复制]

java 将一项活动的数据发送到另一项活动