首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android 圖片瀏覽器 NullPointerException:GridView 初始化順序錯誤

     編輯:程式設計疑難解答

錯誤原因

在 onCreate() **之前** 就嘗試 findViewById(R.id.gridview1):

// 錯誤位置:類成員變數初始化階段執行,此時 Layout 尚未 inflate,root view 為 null
GridView gridview = (GridView) findViewById(R.id.gridview1); 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main); // Layout 這纔被載入
    // ...
}

findViewById 依賴 setContentView() 後的視圖樹,在此之前調用必回傳 null,後續 gridview.setAdapter() 拋出 NPE。

修正代碼

public class MainActivity extends Activity {
    private int[] imageId = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.e, R.drawable.f, R.drawable.g, R.drawable.h, R.drawable.i};
    private ImageSwitcher imageSwitcher;
    private GridView gridView; // 宣告為成員變數

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); // 1. 先載入 Layout

        // 2. 再 findViewById
        gridView = findViewById(R.id.gridview1);
        imageSwitcher = findViewById(R.id.imageSwitcher1);

        // 3. 配置 ImageSwitcher 動畫與 Factory
        imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));
        imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
        imageSwitcher.setFactory(() -> {
            ImageView iv = new ImageView(MainActivity.this);
            iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
            iv.setLayoutParams(new ImageSwitcher.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            return iv;
        });
        imageSwitcher.setImageResource(imageId[6]); // 預設顯示第7張

        // 4. 設定 GridView Adapter
        gridView.setAdapter(new BaseAdapter() {
            @Override public int getCount() { return imageId.length; }
            @Override public Object getItem(int position) { return imageId[position]; }
            @Override public long getItemId(int position) { return position; }
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ImageView iv;
                if (convertView == null) {
                    iv = new ImageView(MainActivity.this);
                    iv.setAdjustViewBounds(true);
                    iv.setMaxWidth(150);
                    iv.setMaxHeight(113);
                    iv.setPadding(5, 5, 5, 5);
                } else {
                    iv = (ImageView) convertView;
                }
                iv.setImageResource(imageId[position]);
                return iv;
            }
        });

        // 5. 設定點擊切換大圖
        gridView.setOnItemClickListener((parent, view, position, id) -> 
            imageSwitcher.setImageResource(imageId[position]));
    }
}

最佳實踐補充

  • **ViewBinding / DataBinding**:現代專案建議啟用,自動生成綁定類,編譯期檢測 ID 錯誤,避免 NPE。
  • **RecyclerView 替代 GridView**:更靈活、效能更好、支援動畫、佈局管理器分離。
  • **圖片載入庫**:實際專案請用 Glide/Picasso/Coil 載入 drawable/網路圖,自動處理縮放、快取、生命週期。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved