2016-03-17 1 views
0

Я накачивание макета в OnCreate(), который уже объявлен в моей деятельности:findViewByID возвращает нуль после установки такого же идентификатора к виду

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

Предположит идентификатора объявлен как Int в моя деятельность.

Позже, после некоторого события я добавление ImageView в этот макет

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

Позже где-то, я хочу, чтобы получить ImageView от ид мы установили ранее:

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

Весь код работает успешно, и Imageview всегда возвращает значение null, напечатанное в журнале.

Примечание: Я не могу сохранить объект изображения, потому что у меня есть много разных видов в реальном проекте. Здесь я описал свою проблему, используя одно изображение. Я сохранил все идентификаторы просмотров, но не могу получить все эти представления, используя findViewById(). Причина, по которой я использовал Calendar.getInstance(). GetTimeInMillis() для генерации идентификатора - это потому, что я хочу уникальный идентификатор каждый раз. Я сохранил все данные макета, включая идентификаторы для последующего использования. Если пользователь снова откроет эту деятельность в любое время, он получит оттуда, где остановился. Поэтому, добавляя любое новое изображение, идентификатор не должен повторяться, который генерируется ранее.

Keypoint: Если я установил дату-время устройства на 2-3 или более дней раньше, тогда он будет работать правильно. Я думаю, что проблема заключается в генерации идентификатора с использованием календаря.

+0

Правильно прочитайте вопрос. Я не могу этого сделать, поскольку я использую множественное представление, а не одно изображение. –

+0

Надеюсь, вы не используете один и тот же идентификатор для всех видов изображений, не так ли? – Rohit5k2

+0

Очевидно нет.И даже если я использую то же самое, почему я получу ** null **? –

ответ

1

Наконец-то я получил решение, используя попытку и ошибку. Как я уже говорил, он работал должным образом до 2 дней, я решил отлаживать с использованием генерируемого и литого идентификатора от 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 на положительный int. Затем я преобразовал один и тот же идентификатор в абсолютное значение, используя:

id = Math.abs (id);

и все работает нормально.

И наконец, мне интересно, почему setId() не дает исключение, если установлено на неположительное int. Они должны дать исключение, поскольку они упомянули, что это должно быть postive int, чтобы любой разработчик узнал, в чем проблема.

+1

Относительно части, где * они должны давать исключение *, когда идентификатор отрицательный, нашел это [ответ] (http://stackoverflow.com/a/13241629/4625829): *** Значение int должно быть положительным, но в противном случае произвольно *** Если мое понимание верное, если предоставленный идентификатор верен, сам андроид вместо этого генерирует неуказанный случайный идентификатор. –

1

Если вы не предоставили контейнер, из которого вам нужно найти представление, например View v = findViewById(id), то это попытается найти представление в используемом xml.

ли это

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

Примечание:

Используйте это, чтобы генерировать идентификатор динамически

int id = System.currentTimeMillis(); 

getTimeInMillis() Возвращает время, представленное в календаре, повторно вычислив время от своих полей если необходимо. Если время не установлено и время не может быть вычислено из текущих значений поля. Это может быть для вас, и вы не должны получать миллисекунды.

Official doc

+0

Не работает .... –

+0

@BrijeshChopda является 'id' положительным int? – Rohit5k2

+0

Его просто ** int **. int может иметь как положительный, так и отрицательный. –

0

При генерации идентификатора программно вы должны использовать следующий код, чтобы установить идентификатор представления,

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { 

    myView.setId(Utils.generateViewId()); 

} else { 

    myView.setId(View.generateViewId()); 

} 

Вы можете использовать это, чтобы установить идентификатор и проверить?

+0

Я не могу использовать это, потому что они генерируют идентификаторы от начала, например, 1,2,3 ..., когда пользователь снова возвращается к активности, и есть вероятность, что другие представления будут иметь эти идентификаторы. –

0

Хорошо, поэтому я пошел и осмотрелся с сообществом и увидел сообщения о том, как динамически добавлять идентификатор в R.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():

Идентификатор должен быть положительным числом.

Обратите внимание, что сгенерированный идентификатор отрицательный. Так что я пошел и изменил поколение Ид к этому:

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! 

Обратите внимание, что идентификатор Теперь генерируемый положительный. Теперь он может как-то идентифицировать его. Надеюсь, это поможет. Удачи. Если вы нашли лучший способ, пожалуйста, дайте мне знать. :)

+1

Я получил то же решение и собираюсь опубликовать, и вы ответили здесь. –

+0

@BrijeshChopda Это сработало? : D –

+0

Отметьте ответ как правильный для того, который, по вашему мнению, является наиболее полезным, чтобы другие пользователи сообщества увидели. Отличная работа. Счастливое кодирование! :) –