在为视图

时间:2016-03-17 19:22:59

标签: android android-layout view findviewbyid

我在onCreate()中夸大布局,这已在我的活动中声明:

layout = (RelativeLayout) findViewById(R.id.layout);

假设 id 在我的活动中被声明为 int

稍后,在某些事件之后,我要将imageview添加到此布局

id = (int) Calendar.getInstance().getTimeInMillis();
ImageView imageView = new ImageView(context);
imageView.setImageResource(R.drawable.ic_launcher);    
imageView.setId(id);
layout.addView(imageView);

稍后某处,我想从之前设置的 id 中获取imageView:

ImageView imageView = (ImageView) findViewById(id);
if (imageView == null)
    Log.e("Test", "imageview is null");

所有代码都成功运行,Imageview始终返回null,如日志中所示。

  

注意:我无法保留imageview本身的对象,因为我在实际项目中有许多不同的视图。在这里,我使用单个imageview描述了我的问题。我已经存储了所有视图的ID,但无法使用 findViewById()获取所有这些视图。我之所以使用 Calendar.getInstance()。getTimeInMillis()来生成id是因为我每次都想要一个唯一的id。我已经存储了所有布局数据,包括id以供以后使用。如果用户随时再次打开此活动,他将从他离开的地方开始。因此,在添加任何新的imageview时,不得重复先前生成的id。

     

关键点:如果我将设备日期时间设置为2-3天或更长时间,那么它可以正常工作。我认为问题在于使用日历生成id。

4 个答案:

答案 0 :(得分:1)

如果您没有提供需要查找View v = findViewById(id)之类视图的容器,那么这将尝试在使用过的xml中查找该视图。

这样做

ImageView imageView = (ImageView) layout.findViewById(id);
if (imageView == null)
    Log.e("Test", "imageview is null");

注意:

使用它来动态生成id

int id = System.currentTimeMillis();

getTimeInMillis()返回日历表示的时间,必要时从其字段重新计算时间。如果未设置时间,则无法从当前字段值计算时间。这可能是你的情况,你不能得到毫秒。

Official doc

答案 1 :(得分:1)

最后,我使用try和error得到了解决方案。 正如我已经提到它在2天之前正常工作,我决定使用生成的id进行调试,并通过每次减少日期来从long转换为int。假设计数器在活动中被声明为int

            ImageView imageView = new ImageView(context);
            imageView.setImageResource(R.drawable.ic_launcher);
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - counter);
            counter++;
            String date = getDate(calendar.getTimeInMillis(), "dd/MM/yyyy hh:mm:ss.SSS");
            Log.e("Test", "Date :" + date);
            int id = (int) calendar.getTimeInMillis();
            Log.e("Test", "ID:" + id);
            imageView.setId(id);
            layout.addView(imageView);
            imageView = (ImageView) findViewById(id);
            if (imageView == null)
                Log.e("Test", "imageview is null");
            else
                Log.e("Test", "not null");

日志:

03-17 23:13:44.952: E/Test(1469): Date :17/03/2016 11:13:44.952

03-17 23:13:44.952: E/Test(1469): ID:-2018055688

03-17 23:13:44.952: E/Test(1469): imageview is null

03-17 23:13:48.744: E/Test(1469): Date :16/03/2016 11:13:48.745

03-17 23:13:48.744: E/Test(1469): ID:-2104451895

03-17 23:13:48.748: E/Test(1469): imageview is null

03-17 23:13:53.376: E/Test(1469): Date :15/03/2016 11:13:53.380

03-17 23:13:53.376: E/Test(1469): ID:2104120036

03-17 23:13:53.376: E/Test(1469): not null

在这里,我发现过去两天我得到否定 int,在此之前我得到正面 int。正如文档中提到的那样,你应该将id设置为positive int。然后我使用以下方法将相同的id转换为绝对值:

id = Math.abs(id);

一切正常。

最后,我想知道为什么setId()如果设置为非正int则不会给出异常。他们应该提出异常,因为他们已经提到它应该是 postive int 所以任何开发人员都知道问题是什么。

答案 2 :(得分:0)

以编程方式生成id时,您应该使用以下代码来设置视图的ID,

var name = item.GetAttributeValue<string>("name");

你能用它来设置id并测试吗?

答案 3 :(得分:0)

好的,所以我去了社区,浏览了有关如何在R.id中动态添加ID以供findViewById()使用的帖子。起初我认为你应该继续使用View.generateViewId(),但正如你在其中一个答案中所评论的那样,你不喜欢使用它。所以我选择了你的实现并试了一下,添加了一些日志等等。首先,这是我的简单活动代码:

  

MainActivity.java

package com.example.my.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

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

        LinearLayout llmain = (LinearLayout) findViewById(R.id.ll_main);

        int id = (int) System.currentTimeMillis();
        Log.d("SAMPLE", "Generated ID: " + id);
        ImageView imageView = new ImageView(this);
        imageView.setImageResource(R.drawable.sample_img);
        imageView.setId(id);
        llmain.addView(imageView);

        Log.d("SAMPLE", "Get ID: " + imageView.getId());

        ImageView iv = (ImageView) findViewById(id);
        if (iv == null) {
            Log.d("SAMPLE", "ID: IMAGE VIEW IS NULL!");
        } else {
            Log.d("SAMPLE", "ID: ImageView not null!");
        }
    }
}

所以我去尝试了..这是日志..

03-18 10:54:47.907 29562-29562/com.example.my.myapplication D/SAMPLE: Generated ID: -2019192733
03-18 10:54:47.913 29562-29562/com.example.my.myapplication D/SAMPLE: Get ID: -2019192733
03-18 10:54:47.913 29562-29562/com.example.my.myapplication D/SAMPLE: ID: IMAGE VIEW IS NULL!

然后我从setId()的文档中看到了:

  

标识符应为正数。

请注意,之前生成的ID为否定。所以我把id生成改为:

int id = Math.abs((int) System.currentTimeMillis());

尝试再次运行它,这是日志:

03-18 10:58:05.073 32662-32662/? D/SAMPLE: Generated ID: 2018995567
03-18 10:58:05.080 32662-32662/? D/SAMPLE: Get ID: 2018995567
03-18 10:58:05.080 32662-32662/? D/SAMPLE: ID: ImageView not null!

请注意,现在生成的ID为正面。现在它能够以某种方式识别它。希望这会有所帮助。祝好运。如果您确实找到了更好的方法,请告诉我。 :)