在Horizo​​ntal Recyclerview中动态插入空行

时间:2018-09-24 15:26:34

标签: android android-recyclerview recycler-adapter

我只是为我准备好此动态布局的第一步,但我无法弄清楚自己在做什么错。 我有以下字符串:
AAA__AB /
_AAAAAA /
_AAABBB /

我应该将上述字符串转换为房间布局,从而:
A-表示可用房间
B-代表已预订的房间
_-表示空格
/-代表新行

我一直在遵循本教程Dynamic bus seats layout来尝试制作一个可以在 RecyclerView 中动态创建公寓房间布局的应用。
我有一个水平方向的recyclerview作为父recyclerView。我有一个适配器和一个来自Web服务器的数据源。
除了应该强制recyclerview添加新行/行以使其余视图可以在新行/行中对齐之外,所有功能都可以正常运行,而NEW_LINE功能除外 请帮助

以下是我得到的
The way my layout looks like as at now


以下是我想要的
The intended layout


Main Activity.java

...rest of the code
//Displaying the rooms and trying to make the layout
private void display_rooms_details(){

    ArrayList house_rooms;
    house_rooms=new ArrayList<>();
    for (int i = 0; i < rooms_list.size(); i++)
    {
        if(rooms_list.get(i).getType()==0){
            house_rooms.add(new Decode_rooms(Decode_rooms.AVAILABLE_ROOMS, rooms_list.get(i).getRoom_type(), rooms_list.get(i).getRoom_number(), rooms_list.get(i).getRoom_name(), rooms_list.get(i).getRoom_symbol(), rooms_list.get(i).getRoom_tenant()));
        }
        if(rooms_list.get(i).getType()==1){
            house_rooms.add(new Decode_rooms(Decode_rooms.BOOKED_ROOMS, rooms_list.get(i).getRoom_type(), rooms_list.get(i).getRoom_number(), rooms_list.get(i).getRoom_name(), rooms_list.get(i).getRoom_symbol(), rooms_list.get(i).getRoom_tenant()));
        }
        if(rooms_list.get(i).getType()==2){
            house_rooms.add(new Decode_rooms(Decode_rooms.NEW_LINE, rooms_list.get(i).getRoom_type(), rooms_list.get(i).getRoom_number(), rooms_list.get(i).getRoom_name(), rooms_list.get(i).getRoom_symbol(), rooms_list.get(i).getRoom_tenant()));
        }
        if(rooms_list.get(i).getType()==3){
            house_rooms.add(new Decode_rooms(Decode_rooms.SPACE, rooms_list.get(i).getRoom_type(), rooms_list.get(i).getRoom_number(), rooms_list.get(i).getRoom_name(), rooms_list.get(i).getRoom_symbol(), rooms_list.get(i).getRoom_tenant()));
        }

    }
    RecyclerView myrv= findViewById(R.id.recycleview_item_list);
    Adapter_display_rooms myAdapter= new Adapter_display_rooms(this,house_rooms);
    myrv.setLayoutManager(new LinearLayoutManager(this, OrientationHelper.HORIZONTAL,false));
    myrv.setItemAnimator(new DefaultItemAnimator());
    myrv.setAdapter(myAdapter);

}


Adapter_display_rooms

 public class Adapter_display_rooms extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

    //Declare context and the class with our list
    private static Context mContext;
    int total_types;
    private static ArrayList<Decode_rooms> rooms_list; //Our data class... this one contains the get and set methods to decode the data for us

    //Available rooms layout class
    public static class ActualRoomsViewHolder extends RecyclerView.ViewHolder {
        CardView cardview;
        TextView txtType;
        ImageView image;

        public ActualRoomsViewHolder(View itemView) {
            super(itemView);
            this.cardview= itemView.findViewById(R.id.layout_available_rooms);
            this.image =  itemView.findViewById(R.id.room_icon);
            this.txtType = itemView.findViewById(R.id.room_name);
        }
    }


    //New Line layout class
    public static class NewLineViewHolder extends RecyclerView.ViewHolder {

        LinearLayout linearlayout;

        public NewLineViewHolder(View itemView) {
            super(itemView);
            this.linearlayout =  itemView.findViewById(R.id.layout_newline);
        }
    }


    //New Line layout class
    public static class AddSpaceViewHolder extends RecyclerView.ViewHolder {

        TextView txtType;

        public AddSpaceViewHolder(View itemView) {
            super(itemView);
            this.txtType =  itemView.findViewById(R.id.add_space);
        }
    }



    //END OF VIEWHOLDER CLASSES

    //The Class Constructor
    public Adapter_display_rooms(Context mContext, ArrayList<Decode_rooms> rooms_list) {
        this.mContext = mContext;
        this.rooms_list = rooms_list;
        total_types=rooms_list.size();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case Decode_rooms.AVAILABLE_ROOMS:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_rooms_layout_listview_rooms, parent, false);
                return new ActualRoomsViewHolder(view);
            case Decode_rooms.BOOKED_ROOMS:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_rooms_layout_listview_rooms, parent, false);
                return new ActualRoomsViewHolder(view);
            case Decode_rooms.NEW_LINE:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_rooms_layout_listview_newline, parent, false);
                return new NewLineViewHolder(view);
            case Decode_rooms.SPACE:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_rooms_layout_listview_space, parent, false);
                return new AddSpaceViewHolder(view);
        }
        return null;

    }

    @Override
    public int getItemViewType(int position) {

        switch (rooms_list.get(position).type) {
            case 0:
                return Decode_rooms.AVAILABLE_ROOMS;
            case 1:
                return Decode_rooms.BOOKED_ROOMS;
            case 2:
                return Decode_rooms.NEW_LINE;
            case 3:
                return Decode_rooms.SPACE;
            default:
                return -1;
        }
    }
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        final Decode_rooms object = rooms_list.get(position);
        if (object != null) {
            switch (object.type) {
                case Decode_rooms.AVAILABLE_ROOMS:
                    ((ActualRoomsViewHolder) holder).image.setImageResource(R.drawable.ic_seats_book);
                    ((ActualRoomsViewHolder) holder).txtType.setText(object.getRoom_number());
                    ((ActualRoomsViewHolder) holder).cardview.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Intent intent=new Intent(mContext, Available_room_details.class);
                            intent.putExtra("room_number",object.getRoom_number());
                            intent.putExtra("room_name",object.getRoom_name());
                            intent.putExtra("room_type",object.getRoom_type());
                            mContext.startActivity(intent);
                        }
                    });
                    ((ActualRoomsViewHolder) holder).cardview.setOnLongClickListener(new View.OnLongClickListener() {
                        @Override
                        public boolean onLongClick(View v) {
                            //Creating the instance of PopupMenu
                            PopupMenu popup = new PopupMenu(mContext,v);
                            //Inflating the Popup using xml file
                            popup.getMenuInflater()
                                    .inflate(R.menu.menu_available_room_options, popup.getMenu());

                            //registering popup with OnMenuItemClickListener
                            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                                public boolean onMenuItemClick(MenuItem item) {
                                    Toast.makeText(
                                            mContext,
                                            "You Clicked : " + item.getTitle(),
                                            Toast.LENGTH_SHORT
                                    ).show();
                                    return true;
                                }
                            });

                            popup.show(); //showing popup menu
                            return false;
                        }
                    });
                    break;
                case Decode_rooms.BOOKED_ROOMS:
                    ((ActualRoomsViewHolder) holder).image.setImageResource(R.drawable.ic_seats_booked);
                    ((ActualRoomsViewHolder) holder).txtType.setText(object.getRoom_number());
                    ((ActualRoomsViewHolder) holder).cardview.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Intent intent=new Intent(mContext, Booked_room_details.class);
                            intent.putExtra("room_number",object.getRoom_number());
                            intent.putExtra("room_name",object.getRoom_name());
                            intent.putExtra("room_type",object.getRoom_type());
                            mContext.startActivity(intent);
                        }
                    });
                    ((ActualRoomsViewHolder) holder).cardview.setOnLongClickListener(new View.OnLongClickListener() {
                        @Override
                        public boolean onLongClick(View v) {
                            //Creating the instance of PopupMenu
                            PopupMenu popup = new PopupMenu(mContext,v);
                            //Inflating the Popup using xml file
                            popup.getMenuInflater()
                                    .inflate(R.menu.menu_booked_room_options, popup.getMenu());

                            //registering popup with OnMenuItemClickListener
                            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                                public boolean onMenuItemClick(MenuItem item) {
                                    Toast.makeText(
                                            mContext,
                                            "You Clicked : " + item.getTitle(),
                                            Toast.LENGTH_SHORT
                                    ).show();
                                    return true;
                                }
                            });

                            popup.show(); //showing popup menu
                            return false;
                        }
                    });
                    break;
                case Decode_rooms.NEW_LINE:

                    break;
                case Decode_rooms.SPACE:
                    ((AddSpaceViewHolder) holder).txtType.setText("Space "+object.getRoom_number());
                    break;
                default:
                    ((ActualRoomsViewHolder) holder).txtType.setText("Default "+object.getRoom_number());
                    break;
            }
        }
    }

    @Override
    public int getItemCount() {
        return rooms_list.size();
    }


解码房间java

    public class Decode_rooms {
    //Aid the custom adapter in inflating different types of layouts
    public static final int AVAILABLE_ROOMS = 0;
    public static final int BOOKED_ROOMS = 1;
    public static final int NEW_LINE = 2;
    public static final int SPACE = 3;

    String room_type,room_number,room_name,room_symbol,room_tenant;
    public int type; //This variable will hold the type of data i.e THE ROOM SYMBOL .. It'll tell the adapter the layout to inflate


    public Decode_rooms(int type,String room_type, String room_number, String room_name, String room_symbol, String room_tenant) {
        this.type = type;
        this.room_type = room_type;
        this.room_number = room_number;
        this.room_name = room_name;
        this.room_symbol = room_symbol;
        this.room_tenant = room_tenant;
    }

    //The setter methods

    public void setType(int type) {
        this.type = type;
    }

    public void setRoom_type(String room_type) {
        this.room_type = room_type;
    }

    public void setRoom_number(String room_number) {
        this.room_number = room_number;
    }

    public void setRoom_name(String room_name) {
        this.room_name = room_name;
    }

    public void setRoom_symbol(String room_symbol) {
        this.room_symbol = room_symbol;
    }

    public void setRoom_tenant(String room_tenant) {
        this.room_tenant = room_tenant;
    }

    //The getter methods

    public int getType() {
        return type;
    }

    public String getRoom_type() {
        return room_type;
    }

    public String getRoom_number() {
        return room_number;
    }

    public String getRoom_name() {
        return room_name;
    }

    public String getRoom_symbol() {
        return room_symbol;
    }

    public String getRoom_tenant() {
        return room_tenant;
    }
}

父XML

    <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/recyclerview" />



</android.support.design.widget.CoordinatorLayout>


回收站视图

    <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycleview_item_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        android:background="@color/blue"
        android:elevation="2dp"
        android:layout_margin="10dp"/>
</android.support.constraint.ConstraintLayout>


“卡片”视图/房间的单个行项

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_available_rooms"
    android:clickable="true"
    android:foreground="?android:attr/selectableItemBackground"
    android:layout_width="@dimen/room_width"
    android:layout_height="@dimen/room_height"
    android:layout_margin="@dimen/roomGaping"
    android:orientation="horizontal"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardCornerRadius="4dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/room_icon"
            android:background="@color/black"
            android:layout_width="match_parent"
            android:layout_height="@dimen/room_width"
            android:scaleType="centerCrop"/>
        <TextView
            android:id="@+id/room_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textColor="#2d2d2d"
            android:textSize="13sp"
            android:text="Room Name"/>
    </LinearLayout>
</android.support.v7.widget.CardView>


新的行布局

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_newline"
    android:layout_width="match_parent"
    android:layout_height="@dimen/room_height"
    android:background="@color/grey_background"
    android:orientation="horizontal">

</LinearLayout>

1 个答案:

答案 0 :(得分:0)

您想要的是GridLayoutManager,其列数为所有行的最大长度。 (您可以将其设置为所有输入的长度的lcm)

遍历每个输入并根据需要设置列范围。让我知道是否有任何不清楚的地方。

编辑:添加示例代码

TestActivity.java

public class TestActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;

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

        mRecyclerView = findViewById(R.id.recycler_view);

        final String[] inputs = new String[3];
        inputs[0] = "AAA__AB/";
        inputs[1] = "_AAAAAA/";
        inputs[2] = "_ABB/";

        final StringBuilder sb  = new StringBuilder();
        for(int i =0; i < inputs.length; i++) {
            sb.append(inputs[i]);
        }

        String[] modifiedInput = sb.toString().split("/");

        final int lcm = getLcm(modifiedInput);

        GridLayoutManager manager = new GridLayoutManager(getApplicationContext(), lcm);
        manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int i) {
                if(sb.toString().charAt(i) == '/') {
                    return lcm;
                }
                else {
                    int index = 0;
                    for(int j = 0; j< inputs.length; j++) {
                        if(i < index+inputs[j].length()) {
                            if(inputs[j].contains("/")) return lcm / (inputs[j].length()-1);
                            else return lcm / inputs[j].length();
                        }
                        else {
                            index += inputs[j].length();
                        }
                    }
                    throw new IllegalStateException("Wrong index");
                }
            }
        });


        List<String> inputDataList = new ArrayList<>();
        String flatInputData = sb.toString();
        for(int i = 0; i < flatInputData.length(); i++) {
            inputDataList.add(String.valueOf(flatInputData.charAt(i)));
        }
        Adapter adapter = new Adapter(inputDataList);
        mRecyclerView.setAdapter(adapter);
        mRecyclerView.setLayoutManager(manager);

    }

    private int getLcm(String[] modifiedInputs) {
        int lcm = modifiedInputs[0].length();
        for(int i = 1; i< modifiedInputs.length; i++) {
            lcm = lcm(lcm, modifiedInputs[i].length());
        }

        return lcm;
    }

    public static  int lcm(int a, int b) {
        return a/gcd(a,b) * b;
    }

    public static int gcd(int a, int b){
        if (a<b) return gcd(b,a);
        if (a%b==0) return b;
        else return gcd(b, a%b);
    }
}

Adapter.java

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {

    public List<String> data;

    public Adapter(List<String> data) {
        this.data = data;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(android.R.layout.simple_list_item_1, viewGroup, false));
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        String text = data.get(i);
        if(!text.equals("/"))
            viewHolder.textView.setText(text);
    }

    @Override
    public int getItemCount() {
        if(data == null) {
            return 0;
        }
        else {
            return data.size();
        }
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(android.R.id.text1);
        }
    }
}

Screenshot