如何向GridView添加多个布局?

时间:2015-08-13 11:07:41

标签: android

我的活动:

public class PassCodeActivity extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_passcode);
        GridView gridView = (GridView) findViewById(R.id.grid_passcode_button);



        PassCodeAdapter mPassCodeAdapter = new PassCodeAdapter(this);
        gridView.setAdapter(mPassCodeAdapter);

        gridView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // TODO Auto-generated method stub


            }
        });
    }

}

我的适配器

public class PassCodeAdapter extends BaseAdapter {

    private final int VIEW_TYPE_ONE = 0;
    private final int VIEW_TYPE_TWO = 1;
    private final int VIEW_TYPE_THREE = 2;

    private Context mContext;

    private String[] mKeyPadStringType1 = {"1","0"};
    private String[] mKeyPadStringType2 = {"2","3","4","5","6","7","8","9"};
    private String[] mKeyPadWord = {"ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"};


    private ArrayList<Integer> pageListToRemoveBtn; 
    // Constructor
    public PassCodeAdapter(Context mContext) {
        this.mContext = mContext;
    }

    @Override
    public int getCount() {
        return 12;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

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

    @Override
    public int getItemViewType(int position) {
        // TODO Auto-generated method stub
        if (position == 9 || position == 11) {
            return VIEW_TYPE_THREE;
        } else if (position == 0 || position == 10) {
            return VIEW_TYPE_ONE;
        } else {
            return VIEW_TYPE_TWO;
        }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        pageListToRemoveBtn = new ArrayList<Integer>();
        pageListToRemoveBtn.add(9);
        int type = getItemViewType(position);
        ViewHolder viewHolder = null;
        ViewHolder.ViewHolderWithWord viewHolderWithWord = null;
        ViewHolder.ViewHolderWithImage viewHolderWithImage = null;
        if (type == VIEW_TYPE_ONE) {
            if (convertView == null) {
                // inflate the GridView item layout
                LayoutInflater inflater = LayoutInflater.from(mContext);
                convertView = inflater.inflate(R.layout.item_passcode_keypad, parent, false);

                // initialize the view holder
                viewHolder = new ViewHolder();
                viewHolder.mKeyPad = (TextView) convertView.findViewById(R.id.txt_passcode_keypad);
                convertView.setTag(viewHolder);
            } else {
                // recycle the already inflated view
                viewHolder = (ViewHolder) convertView.getTag();
            }

            // update the item view
            viewHolder.mKeyPad.setText(mKeyPadStringType1[position]);
        }
        else if (type == VIEW_TYPE_TWO) {
            if (convertView == null) {
                // inflate the GridView item layout
                LayoutInflater inflater = LayoutInflater.from(mContext);
                convertView = inflater.inflate(R.layout.item_passcode_keypad_with_words, parent, false);

                // initialize the view holder
                viewHolderWithWord = new ViewHolder.ViewHolderWithWord();
                viewHolderWithWord.mKeyPad = (TextView) convertView.findViewById(R.id.txt_passcode_number);
                viewHolderWithWord.mKeyPadWord = (TextView) convertView.findViewById(R.id.txt_passcode_word);
                convertView.setTag(viewHolderWithWord);
            } else {
                // recycle the already inflated view
                viewHolderWithWord = (ViewHolder.ViewHolderWithWord) convertView.getTag();
            }

            // update the item view
            viewHolderWithWord.mKeyPad.setText(mKeyPadStringType2[position]);
            viewHolderWithWord.mKeyPadWord.setText(mKeyPadWord[position]);
        }
        else if (type == VIEW_TYPE_THREE) {
            if (convertView == null) {
                // inflate the GridView item layout
                LayoutInflater inflater = LayoutInflater.from(mContext);
                convertView = inflater.inflate(R.layout.item_passcode_keypad_image, parent, false);

                // initialize the view holder
                viewHolderWithImage = new ViewHolder.ViewHolderWithImage();
                viewHolderWithImage.mKeyPadImage = (ImageView) convertView.findViewById(R.id.img_passcode_keypad);
                convertView.setTag(viewHolderWithImage);
            } else {
                // recycle the already inflated view
                viewHolderWithImage = (ViewHolder.ViewHolderWithImage) convertView.getTag();
            }
            if(pageListToRemoveBtn.contains(position)){
            // update the item view
            viewHolderWithImage.mKeyPadImage.setImageResource(R.drawable.blank);
            }else{
                viewHolderWithImage.mKeyPadImage.setImageResource(R.drawable.ic_passcode_delete);
            }
        }
        return convertView;
    }

    public static class ViewHolder {
        TextView mKeyPad;

        public TextView getmIcon() {
            return mKeyPad;
        }

        public static class ViewHolderWithWord extends ViewHolder {
            TextView mKeyPadWord;
        }

        public static class ViewHolderWithImage extends ViewHolder {
            ImageView mKeyPadImage;
        }
    }

}

我想要的是这样的:

enter image description here

但我得到这样的东西:

enter image description here

当我触摸GridView时,应用程序将崩溃并显示错误:

08-13 10:44:29.323: E/InputEventReceiver(5843): Exception dispatching input event.
08-13 10:44:29.331: E/AndroidRuntime(5843): FATAL EXCEPTION: main
08-13 10:44:29.331: E/AndroidRuntime(5843): java.lang.ClassCastException: com.itmo.lifelog_2015.ui.adapter.PassCodeAdapter$ViewHolder cannot be cast to com.itmo.lifelog_2015.ui.adapter.PassCodeAdapter$ViewHolder$ViewHolderWithWord
08-13 10:44:29.331: E/AndroidRuntime(5843):     at com.itmo.lifelog_2015.ui.adapter.PassCodeAdapter.getView(PassCodeAdapter.java:103)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.widget.AbsListView.obtainView(AbsListView.java:2251)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.widget.GridView.makeAndAddView(GridView.java:1331)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.widget.GridView.makeRow(GridView.java:331)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.widget.GridView.fillDown(GridView.java:283)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.widget.GridView.fillGap(GridView.java:243)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5036)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3193)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.widget.AbsListView.onTouchEvent(AbsListView.java:3467)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.View.dispatchTouchEvent(View.java:7127)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2170)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1905)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1925)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1379)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.app.Activity.dispatchTouchEvent(Activity.java:2396)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1873)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.View.dispatchPointerEvent(View.java:7307)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3172)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3117)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4153)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4132)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4224)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:163)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4203)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4243)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.Choreographer.doCallbacks(Choreographer.java:555)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.Choreographer.doFrame(Choreographer.java:523)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.os.Handler.handleCallback(Handler.java:615)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.os.Handler.dispatchMessage(Handler.java:92)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.os.Looper.loop(Looper.java:137)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at android.app.ActivityThread.main(ActivityThread.java:4745)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at java.lang.reflect.Method.invokeNative(Native Method)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at java.lang.reflect.Method.invoke(Method.java:511)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-13 10:44:29.331: E/AndroidRuntime(5843):     at dalvik.system.NativeStart.main(Native Method)

请告诉我如何解决这个问题!提前谢谢!

1 个答案:

答案 0 :(得分:0)

在静态viewholder类之外声明不同的视图。

使用此方法有两个视图(我认为在您的情况下不需要)

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    class ViewHolder0 extends RecyclerView.ViewHolder {
        ...
    }

    class ViewHolder2 extends RecyclerView.ViewHolder {
        ...
    }

    @Override
    public int getItemViewType(int position) {
        // Just as an example, return 0 or 2 depending on position
        // Note that unlike in ListView adapters, types don't have to be contiguous
        return position % 2 * 2;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         switch (viewType) {
             case 0: return new ViewHolder0(...);
             case 2: return new ViewHolder2(...);
             ...
         }
    }
  }

这将解决类强制转换异常

关于实现拨号盘视图

采用固定大小的gridview,即固定数量的列和固定行,每个网格项应具有相同的视图 - 相同的布局文件 - 只是有条件地基于网格的每个项目位置

  • 禁用textview(如1号和#1的情况)
  • 使背景变灰 - 最后一行极端位置