iPhone Tabs for Android!

作者利用空闲时间尝试为Android应用程序复制iPhone的UI元素,特别是底部的标签栏导航。通过此代码片段,开发者可以了解如何在Android应用中实现类似的标签栏,并注册点击监听器。

Postby rolle3k » Mon May 31, 2010 9:37 pm

Hiya,

I was bored and had some spare time and I really like the iPhone ui elements so I started cloning the tabs. Code has been written with love.

Everything you need to know is in the source code. Shows you how to add tabs and how to register a click tab listener.

4 Tabs:

Image
Image
Image

Screenshot which shows 3 Tabs:

Image

You can add as much tabs as you like (make sure you resize the icons correctly). Oh well, hope you like it!

Download:  http://ul.to/1678n1

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package com.example.assignment.client; import android.content.Intent; import android.os.Bundle; import android.view.Gravity; import android.view.View; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.widget.ViewPager2; import com.example.assignment.R; import com.example.assignment.client.repo.ClientItem; import com.example.assignment.databinding.ActivityClientBinding; import com.example.assignment.login.CreateIDActivity; import com.example.assignment.login.LoginChooseActivity; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.tabs.TabLayoutMediator; import com.tplink.apps.architecture.BaseMvvmActivity; import com.tplink.design.menu.TPListPopupWindow; import com.tplink.design.menu.TPSimplePopupAdapter; import com.tplink.design.menu.TPSimplePopupMenuItem; import java.util.ArrayList; import java.util.List; public class ClientActivity extends BaseMvvmActivity<ActivityClientBinding> { private int currentPagePosition = 0; // 当前页面位置 @Nullable @Override protected ActivityClientBinding bindContentView(@Nullable Bundle bundle) { return ActivityClientBinding.inflate(getLayoutInflater()); } @Override protected void subscribeViewModel(@Nullable Bundle bundle) { // 设置适配器 ViewPagerAdapter adapter = new ViewPagerAdapter(this); viewBinding.viewPager.setAdapter(adapter); viewBinding.viewPager.setOffscreenPageLimit(2); // 预加载所有页面 // 添加页面切换监听 viewBinding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { currentPagePosition = position; } }); // 设置Fragment监听(延迟执行以确保Fragment已创建) viewBinding.viewPager.post(() -> { setupFragmentListeners(); if (viewBinding.viewPager.getCurrentItem() == 1) { // 如果初始在页面2 currentPagePosition = 1; // 手动设置位置 } }); // 启用嵌套滚动 View child = viewBinding.viewPager.getChildAt(0); if (child instanceof RecyclerView) { RecyclerView recyclerView = (RecyclerView) child; recyclerView.setNestedScrollingEnabled(true); } // 关联TabLayout和ViewPager2 new TabLayoutMediator(viewBinding.tabLayout, viewBinding.viewPager, (tab, position) -> { if (position == 0) { tab.setText("Main"); } else { tab.setText("Guest"); } }).attach(); viewBinding.toolbar.setOnMenuItemClickListener(v -> { Intent intent = new Intent(ClientActivity.this, BlockListActivity.class); startActivity(intent); return false; }); } // 为Fragment设置监听器 private void setupFragmentListeners() { Fragment mainFragment = getSupportFragmentManager().findFragmentByTag("f0"); // ViewPager2的Fragment标签规则:f + position Fragment guestFragment = getSupportFragmentManager().findFragmentByTag("f1"); if (mainFragment instanceof MainNetworkFragment) { ((MainNetworkFragment) mainFragment).setOnItemLongClickListener((view, position, isOnline) -> { showPopupMenuForItem(view, position, isOnline); }); } if (guestFragment instanceof GuestNetworkFragment) { ((GuestNetworkFragment) guestFragment).setOnItemLongClickListener((view, position, isOnline) -> { showPopupMenuForItem(view, position, isOnline); }); } } // 修改弹出窗口方法,增加位置参数 public void showPopupMenuForItem(View v, int itemPosition, boolean isOnline) { List<TPSimplePopupMenuItem> menuItems = new ArrayList<>(); menuItems.add(new TPSimplePopupMenuItem("Block", R.drawable.ic_block_black)); if(!isOnline) { menuItems.add(new TPSimplePopupMenuItem("Delete", R.drawable.ic_delete_24)); } TPListPopupWindow popupWindow = new TPListPopupWindow(this, v); popupWindow.setAdapter(new TPSimplePopupAdapter(this, menuItems)); popupWindow.setDropDownGravity(Gravity.END); // 添加菜单点击处理 popupWindow.setOnItemClickListener((parent, view1, menuPosition, id) -> { // 通过菜单位置区分点击项 if (menuPosition == 0) { // "Block" 是第一个菜单项 handleBlockAction(itemPosition, isOnline); } else if (menuPosition == 1) { // "Delete" 是第二个菜单项 handleDeleteAction(itemPosition, isOnline); } // popupWindow.dismiss(); }); popupWindow.show(); } // 处理 Block 操作 private void handleBlockAction(int devicePosition, boolean isOnline) { // 根据位置获取设备信息(需补充获取数据的方法) // ClientItem device = getDeviceByPosition(devicePosition, isOnline); new MaterialAlertDialogBuilder(this) .setTitle("Add to Block List") .setMessage("确定将XX设备加入黑名单?") .setPositiveButton("yes", (dialogInterface, i) -> { // todo sth }) .setNegativeButton("no", null) .show(); } private void handleDeleteAction(int devicePosition, boolean isOnline) { // 根据位置获取设备信息(需补充获取数据的方法) // ClientItem device = getDeviceByPosition(devicePosition, isOnline); new MaterialAlertDialogBuilder(this) .setTitle("Delete") .setMessage("确定删除吗?") .setPositiveButton("yes", (dialogInterface, i) -> { // todo sth }) .setNegativeButton("no", null) .show(); } // 根据位置获取设备(示例方法) // private ClientItem getDeviceByPosition(int position, boolean isOnline) { // // 需要根据当前网络类型获取对应数据源 // List<ClientItem> dataSource = isOnline ? onlineDevices : offlineDevices; // return dataSource.get(position); // } } 我现在需要完成block操作 加入黑名单即删除改item 然后将其加入到blocklist中去 package com.example.assignment.client.repo; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import com.example.assignment.R; import java.util.ArrayList; import java.util.List; public class ClientRepo { private static ClientRepo instance; // 分别存储在线/离线设备(不包含标题) private final MutableLiveData<List<OnlineItem>> onlineDevices = new MutableLiveData<>(); private final MutableLiveData<List<OfflineItem>> offlineDevices = new MutableLiveData<>(); private final MutableLiveData<List<BlockItem>> blockItems = new MutableLiveData<>(); // 新增黑名单数据源 private ClientRepo() { initDeviceData(); // 确保数据初始化 initBlockData(); // 初始化黑名单数据 } // 初始化数据(仅设备) private void initDeviceData() { onlineDevices.setValue(createOnlineItems()); offlineDevices.setValue(createOfflineItems()); } // 单例获取方法 public static synchronized ClientRepo getInstance() { if (instance == null) { instance = new ClientRepo(); } return instance; } // 获取在线设备LiveData public LiveData<List<OnlineItem>> getOnlineDevices() { return onlineDevices; } // 获取离线设备LiveData public LiveData<List<OfflineItem>> getOfflineDevices() { return offlineDevices; } // 添加在线设备(线程安全) public void addOnlineDevice(OnlineItem device) { List<OnlineItem> current = onlineDevices.getValue(); if (current == null) current = new ArrayList<>(); List<OnlineItem> updated = new ArrayList<>(current); updated.add(device); onlineDevices.postValue(updated); } // 移除在线设备(线程安全) public void removeOnlineDevice(int position) { List<OnlineItem> current = onlineDevices.getValue(); if (current == null || position < 0 || position >= current.size()) return; List<OnlineItem> updated = new ArrayList<>(current); updated.remove(position); onlineDevices.postValue(updated); } // 添加离线设备(线程安全) public void addOfflineDevice(OfflineItem device) { List<OfflineItem> current = offlineDevices.getValue(); if (current == null) current = new ArrayList<>(); List<OfflineItem> updated = new ArrayList<>(current); updated.add(device); offlineDevices.postValue(updated); } // 移除离线设备(线程安全) public void removeOfflineDevice(int position) { List<OfflineItem> current = offlineDevices.getValue(); if (current == null || position < 0 || position >= current.size()) return; List<OfflineItem> updated = new ArrayList<>(current); updated.remove(position); offlineDevices.postValue(updated); } public void clearAllOfflineDevices() { // 执行实际的清除操作,比如清除数据库或网络请求等 // 然后更新仓库的LiveData(如果仓库有维护LiveData的话) // 这里假设仓库有一个方法可以清除所有离线设备,并更新LiveData // 例如:如果仓库有一个MutableLiveData<List<OfflineItem>> offlineDevicesLiveData; offlineDevices.postValue(new ArrayList<>()); } // 更新在线设备(示例) public void updateOnlineDevice(int position, OnlineItem newDevice) { List<OnlineItem> current = onlineDevices.getValue(); if (current == null || position < 0 || position >= current.size()) return; List<OnlineItem> updated = new ArrayList<>(current); updated.set(position, newDevice); onlineDevices.postValue(updated); } // 获取黑名单LiveData public LiveData<List<BlockItem>> getBlockItems() { return blockItems; } // 添加黑名单项(线程安全) public void addBlockItem(BlockItem newItem) { List<BlockItem> current = blockItems.getValue(); if (current == null) current = new ArrayList<>(); List<BlockItem> updated = new ArrayList<>(current); updated.add(newItem); updateFirstLastMarkers(updated); // 更新首尾标记 blockItems.postValue(updated); } // 统一的首尾标记更新方法(可从ViewModel移至此) private void updateFirstLastMarkers(List<BlockItem> items) { if (items.isEmpty()) return; for (BlockItem item : items) { item.setFirst(false); item.setLast(false); } items.get(0).setFirst(true); items.get(items.size() - 1).setLast(true); } private List<OnlineItem> createOnlineItems() { List<OnlineItem> items = new ArrayList<>(); items.add(new OnlineItem( "Melanie‘s iPhone", R.mipmap.ic_game_console, true, "128 Kb/s", "64 Kb/s", true, R.drawable.ic_wifi_4_16, true, false )); items.add(new OnlineItem( "Melanie‘s Mac1", R.mipmap.ic_laptop, false, "512 Kb/s", "256 Kb/s", true, R.drawable.ic_wifi_1_16, false, false )); items.add(new OnlineItem( "Melanie‘s Mac2", R.mipmap.ic_laptop, false, "512 Kb/s", "256 Kb/s", true, R.drawable.ic_wifi_1_16, false, false )); items.add(new OnlineItem( "Melanie‘s Mac3", R.mipmap.ic_laptop, false, "512 Kb/s", "256 Kb/s", true, R.drawable.ic_wifi_1_16, false, false )); items.add(new OnlineItem( "Melanie‘s Mac4", R.mipmap.ic_laptop, false, "512 Kb/s", "256 Kb/s", true, R.drawable.ic_wifi_1_16, false, false )); items.add(new OnlineItem( "Melanie‘s Mac5", R.mipmap.ic_laptop, false, "512 Kb/s", "256 Kb/s", true, R.drawable.ic_wifi_1_16, false, false )); items.add(new OnlineItem( "Melanie‘s iPhone2", R.mipmap.ic_game_console, false, "1.2 Mb/s", "320 Kb/s", true, R.drawable.ic_wifi_2_16, false, true )); return items; } private List<OfflineItem> createOfflineItems() { List<OfflineItem> items = new ArrayList<>(); items.add(new OfflineItem( "Melanie‘s iPhone1", R.mipmap.ic_game_console, "昨天 14:30", true, false )); items.add(new OfflineItem( "Melanie‘s iPhone2", R.mipmap.ic_game_console, "3天前", false, false )); items.add(new OfflineItem( "Melanie‘s iPhone3", R.mipmap.ic_game_console, "3天前", false, true )); return items; } // 初始化黑名单数据 private void initBlockData() { List<BlockItem> items = new ArrayList<>(); items.add(new BlockMacItem("AA:BB:CC:DD:EE:FF", R.mipmap.ic_other, false, false)); items.add(new BlockClientItem("小米手机", "最后在线:2小时前", R.mipmap.ic_game_console, false, false)); blockItems.setValue(items); } } 是直接使用repo吗 还是说需要通过viewmodel
09-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值