Android findViewById可以';找不到以编程方式生成的视图

Android findViewById可以';找不到以编程方式生成的视图,android,Android,当我调用findViewById()获取按钮(以ImageView的形式)时,它返回null。我已经看过了,我能看出来 findViewById()在setContentView()之后调用 只有一个布局:activity\u main.xml 我没有使用ExpandableListView findViewById()和topbar.findViewById()返回null 我还可能忽略了什么 活动\u main.xml <LinearLayout> <GridView

当我调用
findViewById()
获取按钮(以
ImageView
的形式)时,它返回
null
。我已经看过了,我能看出来

  • findViewById()
    setContentView()之后调用
  • 只有一个布局:
    activity\u main.xml
  • 我没有使用
    ExpandableListView
  • findViewById()
    topbar.findViewById()
    返回
    null
我还可能忽略了什么

活动\u main.xml

<LinearLayout>
 <GridView
   android:id="@+id/topbar_grid">
 </GridView>
</LinearLayout>
TopBarAdapter.java

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initializeTopBar();
        initializeMenu();
    }

    private void initializeTopBar() {
        GridView topbar = (GridView) findViewById(R.id.topbar_grid);
        TopBarAdapter topBarAdapter = new TopBarAdapter(this);
        topbar.setAdapter(topBarAdapter);

        ImageView playButton = (ImageView) findViewById(topBarAdapter.playButtonId);
        // Debugging shows playButton is null here
        // Removing the below statement results in the app 
        // being displayed just fine
        playButton.setOnClickListener(new Button.OnClickListener(){
            public void onClick(View v){
                onPlayButtonClick();
            }
        }); 
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}
public class TopBarAdapter extends BaseAdapter {
    private Context context;
    private View[] views = new View[2];

    public int playButtonId = 2000;
    public int trackLabelId = 2001;

    public TopBarAdapter(Context c){
        context = c;
        createTrackLabel();
        createPlayButton();
    }

    private void createPlayButton(){
        ImageView playButton = new ImageView(context);
        playButton.setImageResource(R.drawable.play_icon);
        playButton.setScaleType(ScaleType.CENTER_CROP);
        playButton.setLayoutParams(new GridView.LayoutParams(50, 50));
        playButton.setId(playButtonId);
        views[1] = playButton;
    }




    @Override
    public int getCount() {
        return views.length;
    }

    @Override
    public Object getItem(int position) {
        return views[position];
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return views[position];
    }
}

播放按钮是否添加到布局的某个位置?它来自哪里? 使用
findViewById
方法的最佳方法是依赖Android Generator ID,因此

     Button playButton = (Button) findViewById(topBarAdapter.playButtonId);
你更应该依靠

按钮播放按钮=(按钮)findViewById(R.id.playButtonId)

假设
带有
id
playbutonid
实际上是
R.layout.activity\u main
指定的当前视图布局的一部分。在查找
topBarAdapter
儿童id时,您应该拨打

Button playButton = (Button) topBarAdapter.findViewById(R.id.playButtonId);

您应该在顶栏上设置
OnItemClickListener

topbar.setOnItemClickListener(new OnItemClickListener() {

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

    }
});
topbar.setOnItemClickListener(新的OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父级、视图、,
内部位置,长id){
}
});

但您从未将playButton添加到活动的视图层次结构,或者我遗漏了什么?@blackbelt:
playButton
是添加到
GridView
TopBarAdapter
的一部分。移除事件监听器可以很好地显示应用程序(包括“播放”按钮)。但是您是否在getView方法中以某种方式返回了“播放”按钮?@blackbelt:我已经添加了
TopBarAdapter
类的其余部分。据我所知:是的,应该归还。我明白了。创建对象时,您应该在createPlayButton内设置onClickListener,或者更好地使用
tobbar.setOnItemClickListener
playButton
(这是
ImageView
,而不是
按钮
。我的原始帖子中的错误)是
TopBarAdapter
的一部分,该适配器设置为my
GridView
。如果我不使用事件监听器调用NPE,它就会呈现得很好:播放按钮就会出现。请记住,我的按钮没有输入到XML中,因此它没有在
R.ID
中生成ID:它是在
TopBarAdapter
中生成的。我只是将
playButton.setOnClickListener()
放在
TopBarAdapter\#createPlayButton()
中,但我假设您的示例也会起作用。