Android多级列表的实现

多级列表是ui入门,没什么特别需要注意的难点,直接上代码:
第一级列表窗口

/**
 * 第一级列表
 * 1.编辑状态下选中一个条目,会弹出底部操作栏
 * 2.非编辑状态下选中条目会跳转到下一级
 * 3.复选框使用ImageView而不是CheckBox
 * 4.编辑状态下,按返回键回到非编辑状态
 */
public class SectionListActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "SectionListActivity";

    @BindView(R.id.tv_title_middle)
    TextView title;
    @BindView(R.id.title_left)
    ImageView back;
    @BindView(R.id.discuss_list_view)
    ListView mListView;
    @BindView(R.id.edit_tv)
    TextView edit;
    @BindView(R.id.filter_tv)
    TextView filter;
    @BindView(R.id.discuss_toolbar)
    LinearLayout mToolbar;
    @BindView(R.id.discuss_close)
    TextView btnClose;
    @BindView(R.id.discuss_open)
    TextView btnOpen;
    @BindView(R.id.discuss_delete)
    TextView btnDelete;

    private Context mContext;
    private boolean isEditable;
    private List mClsSectionList;
    private SectionListAdapter mAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_section_list);
        //使用ButterKnife绑定控件
        ButterKnife.bind(this);

        initView();
        initData();
        initListener();
    }

    private void initData() {
        mContext = this;
        //初始状态为非编辑
        setIsEditable(false);

        //初始化数据源
        mClsSectionList = new ArrayList<>();
        mAdapter = new SectionListAdapter(mClsSectionList, mContext);
        mListView.setAdapter(mAdapter);

        initOfflineData(10);
    }

    //生成模拟数据
    private void initOfflineData(int num) {
        List clsSectionList = new ArrayList<>();

        for (int i = 0; i < num; i++) {
            ClsSection clsSection = new ClsSection();
            clsSection.setIsClosed("isClosed" + i);
            clsSection.setCloseDate("closeDate" + i);
            clsSection.setSectionID("sectionID" + i);
            clsSection.setSectionName("sectionName" + i);
            clsSection.setSectionType("sectionType" + i);
            clsSection.setSectionDesc("sectionDesc" + i);
            clsSection.setSectionLogo("sectionLogo" + i);
            clsSection.setSectionManagerID("sectionManagerID" + i);
            clsSection.setSectionManager("sectionManager" + i);
            clsSectionList.add(clsSection);
        }

        mClsSectionList.addAll(clsSectionList);
        mAdapter.notifyDataSetChanged();
    }

    private void initView() {
        title.setText("一级列表");
        mToolbar.setVisibility(View.GONE);

        filter.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_add_black_24dp, 0, 0, 0);

        edit.setVisibility(View.VISIBLE);
        filter.setVisibility(View.VISIBLE);
    }

    private void initListener() {
        back.setOnClickListener(this);
        edit.setOnClickListener(this);
        btnClose.setOnClickListener(this);
        btnDelete.setOnClickListener(this);
        btnOpen.setOnClickListener(this);
        filter.setOnClickListener(this);

        mListView.setOnItemClickListener((parent, view, position, id) -> {
            ClsSection clsSection = mClsSectionList.get(position);

            if (getIsEditable()) {
                //编辑状态下,点击条目checkbox为显示选中
                if (clsSection.getIsCheckBoxVisible()) {
                    clsSection.setIsChecked(!clsSection.getIsChecked());
                    mAdapter.notifyDataSetChanged();
                }
                //有一个条目被选中就弹出工具条
                for (int i = 0; i < mClsSectionList.size(); i++) {
                    ClsSection section = mClsSectionList.get(i);
                    if (section.getIsChecked()) {
                        mToolbar.setVisibility(View.VISIBLE);
                        break;
                    }
                    //否则隐藏工具条
                    if (i == mClsSectionList.size() - 1) {
                        mToolbar.setVisibility(View.GONE);
                    }
                }
            } else {
                //非编辑状态下,点击条目直接跳转
                String sectionID = clsSection.getSectionID();
                Intent intent = new Intent(mContext, TopicListActivity.class);
                intent.putExtra("sectionID", sectionID);
                startActivity(intent);
            }
        });
    }

    @Override
    public void onClick(View v) {
        //编辑状态下点击返回回到非编辑状态
        //非编辑状态下直接退出
        if (v.getId() == R.id.title_left) {
            if (getIsEditable()) {
                switchEditable();
            } else {
                finish();
            }
        }

        //点击编辑按钮切换编辑状态
        if (v.getId() == R.id.edit_tv) {
            switchEditable();
        }

        //新建页面
        if (v.getId() == R.id.filter_tv) {
            Intent intent = new Intent(mContext, SectionNewActivity.class);
            startActivityForResult(intent, 15874);
        }

        //点击工具条不同按钮调用不同接口
        switch (v.getId()) {
            case R.id.discuss_delete:
            case R.id.discuss_close:
            case R.id.discuss_open:
                Toast.makeText(mContext, "在此处调用接口!", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    //编辑状态下点击返回回到非编辑状态
    //非编辑状态下直接退出
    public void onBackPressed() {
        if (getIsEditable()) {
            switchEditable();
        } else {
            finish();
        }
    }

    public boolean getIsEditable() {
        return isEditable;
    }

    public void setIsEditable(boolean editable) {
        isEditable = editable;
    }

    private void switchEditable() {
        //将属性取反
        setIsEditable(!getIsEditable());

        //遍历并修改数据源
        for (ClsSection clsSection : mClsSectionList) {
            clsSection.setIsCheckBoxVisible(getIsEditable());
            clsSection.setIsChecked(false);
        }

        //通知适配器刷新
        mAdapter.notifyDataSetChanged();
        //隐藏工具条
        mToolbar.setVisibility(View.GONE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

        if (requestCode == 15874 && resultCode == RESULT_OK) {
            refreshData();
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    private void refreshData() {
        Toast.makeText(mContext, "在此处调用接口!", Toast.LENGTH_SHORT).show();
    }
}

第二级列表窗口

/**
 * 第二级列表,接收第一级列表的传过来的sectionID
 */
public class TopicListActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "TopicListActivity";
    @BindView(R.id.section_list_view)
    ListView mListView;
    @BindView(R.id.tv_title_middle)
    TextView title;
    @BindView(R.id.title_left)
    ImageView back;
    @BindView(R.id.edit_tv)
    TextView edit;
    @BindView(R.id.filter_tv)
    TextView filter;
    @BindView(R.id.btn_delete_topic)
    LinearLayout btnDelete;

    private Context mContext;
    private boolean isEditable;
    private List mClsTopicList;
    private TopicListAdapter mAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_topic_list);
        ButterKnife.bind(this);

        initView();
        initData();
        initListener();
    }

    private void initData() {

        mContext = this;
        setIsEditable(false);
        String sectionID = getIntent().getStringExtra("sectionID");
        requestData(sectionID);

        mClsTopicList = new ArrayList<>();
        mAdapter = new TopicListAdapter(mClsTopicList, mContext);
        mListView.setAdapter(mAdapter);

        initOfflineData(20);
    }

    private void requestData(String sectionID) {
        Toast.makeText(mContext, "在此处调用接口", Toast.LENGTH_SHORT).show();
    }

    private void initOfflineData(int sum) {

        List clsTopicList = new ArrayList<>();
        for (int i = 0; i < sum; i++) {
            ClsTopic clsTopic = new ClsTopic();
            clsTopic.setRowNum(" rowNum" + i);
            clsTopic.setSectionID(" sectionID" + i);
            clsTopic.setSectionName(" sectionName" + i);
            clsTopic.setSectionManager(" sectionManager" + i);
            clsTopic.setTopicID(" topicID" + i);
            clsTopic.setTitle(" title" + i);
            clsTopic.setTopicDesc(" topicDesc" + i);
            clsTopic.setCreateDate(" createDate" + i);
            clsTopicList.add(clsTopic);
        }
        mClsTopicList.addAll(clsTopicList);
        mAdapter.notifyDataSetChanged();
    }

    private void initView() {
        title.setText("二级列表");
        filter.setVisibility(View.GONE);
        btnDelete.setVisibility(View.GONE);
        edit.setVisibility(View.VISIBLE);
    }

    private void initListener() {

        btnDelete.setOnClickListener(this);
        edit.setOnClickListener(this);
        back.setOnClickListener(this);
        mListView.setOnItemClickListener((parent, view, position, id) -> {

            ClsTopic clsTopic = mClsTopicList.get(position);
            if (getIsEditable()) {
                if (clsTopic.getIsCheckBoxVisible()) {
                    clsTopic.setIsChecked(!clsTopic.getIsChecked());
                    mAdapter.notifyDataSetChanged();
                }
                for (int i = 0; i < mClsTopicList.size(); i++) {
                    ClsTopic topic = mClsTopicList.get(i);
                    if (topic.getIsChecked()) {
                        btnDelete.setVisibility(View.VISIBLE);
                        break;
                    }
                    if (i == mClsTopicList.size() - 1) {
                        btnDelete.setVisibility(View.GONE);
                    }
                }
            } else {
                String topicID = clsTopic.getTopicID();
                Intent intent = new Intent(mContext, ReplyListActivity.class);
                intent.putExtra("topicID", topicID);
                startActivity(intent);
            }
        });
    }

    @Override
    public void onClick(View v) {

        if (v.getId() == R.id.title_left) {
            if (getIsEditable()) {
                switchEditable();
            } else {
                finish();
            }
        }
        if (v.getId() == R.id.edit_tv) {
            switchEditable();
        }
        if (v.getId() == R.id.btn_delete_topic) {
            Toast.makeText(mContext, "在此处调用接口", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onBackPressed() {

        if (getIsEditable()) {
            switchEditable();
        } else {
            finish();
        }
    }

    private void switchEditable() {
        setIsEditable(!getIsEditable());

        for (ClsTopic clsTopic : mClsTopicList) {
            clsTopic.setIsCheckBoxVisible(getIsEditable());
            clsTopic.setIsChecked(false);
        }
        mAdapter.notifyDataSetChanged();
        btnDelete.setVisibility(View.GONE);
    }

    public boolean getIsEditable() {
        return isEditable;
    }

    public void setIsEditable(boolean editable) {
        isEditable = editable;
    }
}

第三级列表窗口

/**
 * 第三级列表,接收第二级列表的传过来的topicID
 */
public class ReplyListActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "ReplyListActivity";

    @BindView(R.id.reply_list_view)
    ListView mListView;
    @BindView(R.id.tv_title_middle)
    TextView title;
    @BindView(R.id.title_left)
    ImageView back;
    @BindView(R.id.edit_tv)
    TextView edit;
    @BindView(R.id.filter_tv)
    TextView filter;
    @BindView(R.id.btn_delete_reply)
    LinearLayout btnDelete;

    private Context mContext;
    private List mClsReplyList;
    private ReplyListAdapter mAdapter;
    private boolean isEditable;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reply_list);
        ButterKnife.bind(this);

        initView();
        initData();
        initListener();
    }


    private void initData() {

        mContext = this;
        setIsEditable(false);
        String topicID = getIntent().getStringExtra("topicID");
        requestData(topicID);

        mClsReplyList = new ArrayList<>();
        mAdapter = new ReplyListAdapter(mClsReplyList, mContext);
        mListView.setAdapter(mAdapter);

        getOfflineData(20);
    }

    private void requestData(String topicID) {
        Toast.makeText(mContext, "在此处调用接口!", Toast.LENGTH_SHORT).show();
    }

    private void getOfflineData(int num) {

        List clsReplyLists = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            ClsReply clsReply = new ClsReply();
            clsReply.setRowNum("rowNum" + i);
            clsReply.setTopicID("topicID" + i);
            clsReply.setReplyID("replyID" + i);
            clsReply.setReplyContent("replyContent" + i);
            clsReply.setReplyTime("replyTime" + i);
            clsReply.setReplyBoutiqueNum("replyBoutiqueNum" + i);
            clsReply.setReplyTopicNum("replyTopicNum" + i);
            clsReply.setReplyManID("replyManID" + i);
            clsReply.setReplyManName("replyManName" + i);
            clsReplyLists.add(clsReply);
        }

        mClsReplyList.addAll(clsReplyLists);
        mAdapter.notifyDataSetChanged();
    }

    private void initView() {
        title.setText("三级列表");
        filter.setVisibility(View.GONE);
        btnDelete.setVisibility(View.GONE);
        edit.setVisibility(View.VISIBLE);
    }

    private void initListener() {

        back.setOnClickListener(this);
        edit.setOnClickListener(this);
        btnDelete.setOnClickListener(this);
        mListView.setOnItemClickListener((parent, view, position, id) -> {
            ClsReply clsReply = mClsReplyList.get(position);
            if (getIsEditable()) {
                if (clsReply.getIsCheckBoxVisible()) {
                    clsReply.setIsChecked(!clsReply.getIsChecked());
                    mAdapter.notifyDataSetChanged();
                }
                for (int i = 0; i < mClsReplyList.size(); i++) {
                    ClsReply reply = mClsReplyList.get(i);
                    if (reply.getIsChecked()) {
                        btnDelete.setVisibility(View.VISIBLE);
                        break;
                    }
                    if (i == mClsReplyList.size() - 1) {
                        btnDelete.setVisibility(View.GONE);
                    }
                }
            } else {
                String topicID = clsReply.getTopicID();
                Toast.makeText(mContext, topicID, Toast.LENGTH_LONG).show();
            }
        });
    }

    @Override
    public void onClick(View v) {

        if (v.getId() == R.id.title_left) {
            if (getIsEditable()) {
                switchEditable();
            } else {
                finish();
            }
        }

        if (v.getId() == R.id.edit_tv) {
            switchEditable();
        }

        if (v.getId() == R.id.btn_delete_reply) {
            Toast.makeText(mContext, "在此处调用接口", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onBackPressed() {

        if (getIsEditable()) {
            switchEditable();
        } else {
            finish();
        }
    }


    private void switchEditable() {
        setIsEditable(!getIsEditable());

        for (ClsReply clsReply : mClsReplyList) {
            clsReply.setIsCheckBoxVisible(getIsEditable());
            clsReply.setIsChecked(false);
        }
        mAdapter.notifyDataSetChanged();
        btnDelete.setVisibility(View.GONE);
    }

    public boolean getIsEditable() {
        return isEditable;
    }

    public void setIsEditable(boolean editable) {
        isEditable = editable;
    }

三个列表的逻辑其实差不多,任何一个都可以作用通用的模板使用,至于什么时候请求数据,什么时候调用接口,什么时候刷新,都看具体的需求而定

运行效果:

你可能感兴趣的:(Java)