Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >可扩展的Listview Android中的多个倒计时器无法工作

可扩展的Listview Android中的多个倒计时器无法工作
EN

Stack Overflow用户
提问于 2015-10-08 03:51:27
回答 1查看 441关注 0票数 2

从上周开始,我尝试在可扩展列表视图中实现多个倒计时器,我希望将时间缩短到00:00,根据这一点,我需要更新可扩展列表视图的父元素中的文本。

我的问题是:

1)滚动可扩展列表视图计时器重新启动

2)展开和折叠计时器重新启动

( 3)在“子事件”按钮上,我需要更新父母视图上特定位置的文本

我还想实现的另一件事是单击子视图中的一个按钮,我需要更新父视图上的文本,但我被塞在那里了。

这里是我的适配器,包含父适配器和子适配器.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Sent_ListAdapter extends BaseExpandableListAdapter {
    private Context _context;
    **private List<SentModel> _listDataHeader;**
    // child data in format of header title, child title
    **private HashMap<SentModel, List<SentModel>> _listDataChild;**
    private TextView txt_summary;
    private TextView datetime_element;
    private LinearLayout ll_arrowtorecord;
    **private String[] ti;**
    **private CountDownTimer cdt_sent;**
    **private HashMap<TextView, CountDownTimer> counters;**
    **private TextView deadline;**

    public Sent_ListAdapter(Context context, List<SentModel> listDataHeader, HashMap<SentModel, List<SentModel>> listChildData) {
        this._context = context;
        this._listDataHeader = listDataHeader;
        this._listDataChild = listChildData;
        ll_end = new FrameLayout[_listDataHeader.size()];
        ll_closeaceess = new FrameLayout[_listDataHeader.size()];
        ll_whoaccpted = new LinearLayout[_listDataHeader.size()];
        **this.counters = new HashMap<TextView, CountDownTimer>();**
    }

    @Override
    public int getGroupCount() {
        return this._listDataHeader.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition)).size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return this._listDataHeader.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition)).get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        final SentModel headerTitle = (SentModel) getGroup(groupPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.element_sentlist, null);
        }
        ll_arrowtorecord = (LinearLayout) convertView.findViewById(R.id.ll_arrowtorecord);
        ll_arrowtorecord.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (headerTitle.getFile().trim().contains(".mp4")) {
                    Log.v("", TAG + "==video==" + headerTitle.getFile());
                    Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
                    Uri data = Uri.parse(headerTitle.getFile());
                    intent.setDataAndType(data, "video/mp4");
                    startActivity(intent);
                } else if (headerTitle.getFile().trim().contains(".jpg")) {
                    Log.v("", TAG + "==image==" + headerTitle.getFile());
                    Intent gotorecoedactivity = new Intent(context, RecordedAsset.class);
                    gotorecoedactivity.putExtra("image", headerTitle.getFile());
                    startActivity(gotorecoedactivity);
                    overridePendingTransition(R.anim.right_slide_in, R.anim.left_side_out);
                    finish();
                } else {
                    Toast.makeText(context, "No recorded asset is there.", Toast.LENGTH_SHORT).show();
                }
            }
        });
        txt_summary = (TextView) convertView.findViewById(R.id.txt_summary);
        if (headerTitle.get_desc().equalsIgnoreCase("") || headerTitle.get_desc() == null) {
            txt_summary.setText(" Description");
        } else {
            txt_summary.setText(headerTitle.get_desc());
        }
        datetime_element = (TextView) convertView.findViewById(R.id.datetime_element);
        final TextView tv = datetime_element;
        deadline = (TextView) convertView.findViewById(R.id.deadline);
        **if (headerTitle.getRemaining_completion_time().equalsIgnoreCase("") || headerTitle.getRemaining_completion_time() == null) {
            datetime_element.setText("");
        } 
        else if (headerTitle.getRemaining_completion_time().equalsIgnoreCase("00:00:00"))
        {
            tv.setText("Completion time over");
            deadline.setVisibility(View.GONE);
        } 
        else 
        {
            ti = headerTitle.getRemaining_completion_time().split(":");
            int hrs = Integer.parseInt(ti[0]);
            cdt_sent = counters.get(datetime_element);
            int days = Integer.parseInt(headerTitle.getRemaining_days());
            //  int hours1 = datetime_plus(days, Integer.parseInt(ti[0]));
            int min = Integer.parseInt(ti[1]);
            int sec = Integer.parseInt(ti[2]);
            long d1 = TimeUnit.DAYS.toMillis(days);
            long m1 = TimeUnit.MINUTES.toMillis(min);
            long h1 = TimeUnit.HOURS.toMillis(hrs);
            long s1 = TimeUnit.SECONDS.toMillis(sec);
            final long milliseco = d1 + m1 + h1 + s1;
            if (cdt_sent != null) {
                cdt_sent.cancel();
                cdt_sent = null;
            }
            cdt_sent = new CountDownTimer(milliseco, 1000)
            {
                int days = 0;
                int hours1 = 0;
                private String sDate;
                int min = 0;
                int sec = 0;
                @Override
                public void onTick(long millisUntilFinished)
                {
                    millisUntilFinished -= (days * DateUtils.DAY_IN_MILLIS);
                    if (millisUntilFinished > DateUtils.HOUR_IN_MILLIS)
                    {
                        hours1 = (int) (millisUntilFinished / DateUtils.HOUR_IN_MILLIS);
                    }
                    millisUntilFinished -= (hours1 * DateUtils.HOUR_IN_MILLIS);
                    if (millisUntilFinished > DateUtils.MINUTE_IN_MILLIS) 
                    {
                        min = (int) (millisUntilFinished / DateUtils.MINUTE_IN_MILLIS);
                    }
                    millisUntilFinished -= (min * DateUtils.MINUTE_IN_MILLIS);
                    if (millisUntilFinished > DateUtils.SECOND_IN_MILLIS)
                    {
                        sec = (int) (millisUntilFinished / DateUtils.SECOND_IN_MILLIS);
                    }
                    sDate = " " + String.format("%02d", hours1) + "h " + String.format("%02d", min) + "m " + String.format("%02d", sec) + "s ";
                    _listDataHeader.get(groupPosition).setTime(sDate);
                    String hms = String.format("%02d,%02d:%02d:%02d", TimeUnit.MILLISECONDS.toDays(milliseco),TimeUnit.MILLISECONDS.toHours(milliseco),
                            TimeUnit.MILLISECONDS.toMinutes(milliseco) % TimeUnit.HOURS.toMinutes(1),
                            TimeUnit.MILLISECONDS.toSeconds(milliseco) % TimeUnit.MINUTES.toSeconds(1));
                    //  Log.v("", "Bansi"+"==hms=="+hms);
                    tv.setText(_listDataHeader.get(groupPosition).getTime());
                }
                @Override
                public void onFinish() {
                    tv.setText("Completion time over");
                    deadline.setVisibility(View.GONE);
                }
            };
            counters.put(tv, cdt_sent);
            cdt_sent.start();
        }**
        return convertView;
    }

    @SuppressLint("InflateParams")
    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final SentModel childText = (SentModel) getChild(groupPosition, childPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.element_childsent, null);
        }
        ll_whoaccpted[groupPosition] = (LinearLayout) convertView.findViewById(R.id.ll_whoaccpted);
        ll_end[groupPosition] = (FrameLayout) convertView.findViewById(R.id.ll_end);
        ll_closeaceess[groupPosition] = (FrameLayout) convertView.findViewById(R.id.ll_closeaceess);
        txt_whoaccepted = (TextView) convertView.findViewById(R.id.txt_whoaccepted);
        img_block = (ImageView) convertView.findViewById(R.id.img_block);
        img_end = (ImageView) convertView.findViewById(R.id.img_end);
        txt_end = (TextView) convertView.findViewById(R.id.txt_end);
        txt_closeacess = (TextView) convertView.findViewById(R.id.txt_closeacess);
        ll_whoaccpted[groupPosition].setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                showWhoAcceptedpopup(childText.getB_id(), groupPosition + "");
                if (Utils.detectInternetConnection(context)) {
                    new post_WhoAccepted().execute(childText.getB_id(), groupPosition + "");
                } else {
                    progressDialog.showWarningDialog_Click(getString(R.string.no_internet), new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            progressDialog.dialogDismiss();
                            try {
                                Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
                                startActivity(callGPSSettingIntent);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            }
        });
        if (childText.getIs_cancel().equalsIgnoreCase("0")) {
            ll_end[groupPosition].setBackgroundColor(Color.parseColor("#CBCBCB"));
            txt_end.setTextColor(Color.parseColor("#7E7E7E"));
            txt_end.setText("You ended the .");
            txt_end.setGravity(Gravity.CENTER);
            img_end.setImageResource(R.drawable.cross_circleclick);
            ll_end[groupPosition].setClickable(false);
        } else {
            ll_end[groupPosition].setBackgroundColor(Color.parseColor("#650030"));
            txt_end.setTextColor(Color.parseColor("#FF0101"));
            txt_end.setText("End ");
            txt_end.setGravity(Gravity.RIGHT);
            img_end.setImageResource(R.drawable.cross_circle);
            ll_end[groupPosition].setClickable(true);
            if (endornot.get(groupPosition) == 0) {
            } else {
                ll_end[groupPosition].setBackgroundColor(Color.parseColor("#CBCBCB"));
                txt_end.setTextColor(Color.parseColor("#7E7E7E"));
                txt_end.setText("You ended the .");
                img_end.setImageResource(R.drawable.cross_circleclick);
                txt_end.setGravity(Gravity.CENTER);
                ll_end[groupPosition].setClickable(false);
            }
            ll_end[groupPosition].setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.v("", TAG + "==childposition==" + groupPosition);
                    if (endornot.get(groupPosition) == 0) {
                        if (Utils.detectInternetConnection(context)) {
                            new post_EndorClose().execute(childText.getB_id(), "1", groupPosition + "");
                        } else {
                            progressDialog.showWarningDialog_Click(getString(R.string.no_internet), new OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    progressDialog.dialogDismiss();
                                    try {
                                        Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
                                        startActivity(callGPSSettingIntent);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            });
                        }
                    } else {
                    }
                }
            });
        }
        if (childText.getIs_close().equalsIgnoreCase("0")) {
            ll_closeaceess[groupPosition].setBackgroundColor(Color.parseColor("#E7E7E7"));
            txt_closeacess.setTextColor(Color.parseColor("#7E7E7E"));
            txt_closeacess.setText("Access to the closed");
            txt_closeacess.setGravity(Gravity.CENTER);
            ll_closeaceess[groupPosition].setClickable(false);
        } else {
            ll_closeaceess[groupPosition].setBackgroundColor(Color.parseColor("#006500"));
            txt_closeacess.setTextColor(Color.parseColor("#043303"));
            txt_closeacess.setText("Close access to ");
            ll_closeaceess[groupPosition].setClickable(true);
            txt_closeacess.setGravity(Gravity.RIGHT);
            if (aceessdeniedornot.get(groupPosition) == 0) {
            } else {
                ll_closeaceess[groupPosition].setBackgroundColor(Color.parseColor("#E7E7E7"));
                txt_closeacess.setTextColor(Color.parseColor("#7E7E7E"));
                txt_closeacess.setText("Access to the closed");
                txt_closeacess.setGravity(Gravity.CENTER);
                ll_closeaceess[groupPosition].setClickable(false);
            }
            ll_closeaceess[groupPosition].setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.v("", TAG + "==childposition==" + groupPosition);
                    if (aceessdeniedornot.get(groupPosition) == 0) {
                        if (Utils.detectInternetConnection(context)) {
                            new post_EndorClose().execute(childText.getB_id(), "2", groupPosition + "");
                        } else {
                            progressDialog.showWarningDialog_Click(getString(R.string.no_internet), new OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    progressDialog.dialogDismiss();
                                    try {
                                        Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
                                        startActivity(callGPSSettingIntent);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            });
                        }
                    } else {
                    }
                }
            });
        }
        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

请帮帮我,我被困在这里了,我还在努力工作,但我还有时间。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-08 05:27:44

首先,我要说,您的代码实际上是难读的

  1. 尝试使用方法将视图创建代码从getGroupViewgetChildView上的繁忙代码中分离出来。此外,您还可以使用ViewHolder模式在getChildView上保存视图,而不是那些数组(ll_whoaccpted,等等)。
  2. (TextUtils.isEmpty(headerTitle.getRemaining_completion_time())) // TextUtils.isEmpty()可以帮助您更好地检查字符串是空的还是空的,而不是是否为headerTitle.getRemaining_completion_time() == null) )
  3. Sent_ListAdapter实现OnClickListener,而不是每次Android为您的列表获取视图时重新创建侦听器(新建)。在视图参数上添加一个条件,以检查单击了哪个视图类型。
  4. 使用日期和SimpleDataFormat在CountDownTimer上工作,这些手动字符串格式是完全不可读的。

现在谈一谈主题:

滚动可扩展列表视图计时器重新启动

之所以会出现这种情况,是因为ListView重新创建未显示的视图/组(调用getView/getGroup方法)以重用其他数据的行。

如果您想避免这种情况,您应该在getView和getGroup之外创建和启动计数器(构造函数是个好地方)。

关于展开和折叠计时器重新启动

在第一个问题上发生的事情完全一样。

在“子事件”按钮上,我需要更新父视图上特定位置的文本

我并没有真正理解这一点,所以我猜测您想要更改主布局(包含列表视图的TextView )的文本。那么,您需要将该TextView引用到Sent_ListAdapter

或者,与其将泛型上下文传递给Sent_ListAdapter,不如将活动/片段传递给self:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public Sent_ListAdapter(MyActivity activty, List<SentModel> listDataHeader, HashMap<SentModel, List<SentModel>> listChildData) {
            this._myactivity = myactivity;
            this._listDataHeader = listDataHeader;
...
}

// The listener that handles all the events of your Sent_ListAdapter

@Override
public void onClick(View v) {
  if(v.getTag() == "theBoutonThatShouldResetTheCounter") { //or other condition
      myactivite.myTextView.setText("------");
  }
}

编辑

但是,我将如何在构造函数中获得每一行的位置?

您需要从另一个角度考虑: listview使用数据源来显示行。因此,您需要遍历数据源上的元素(在您的例子中是listDataHeader)。类似于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private List<CountDownTimer> counters;

public Sent_ListAdapter(Context context, List<SentModel> listDataHeader, HashMap<SentModel, List<SentModel>> listChildData) {
    ...
    counters = new ArrayList()<>;
    for(SentModel model : listDataHeader) {
        long milliseco = model.getRemainingTimeInMs(); //TODO: create something like this or figure out how to get your couters starting times on ms
        CountDownTimer cdt = new MyCountDownTimer(milliseco, 1000);
        cdt.start(); // I don't know when you want to start your counters, if they start at the same time it could be here
    }
}

public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    ...
    datetime_element = (TextView) convertView.findViewById(R.id.datetime_element);
    deadline = (TextView) convertView.findViewById(R.id.deadline);
    ...
    CountDownTimer cdt = counters.get(groupPosition);
    cdt.setTv1 = datetime_element;
    cdt.setTv2 = deadline;
    ...
}

public class MyCountDownTimer extends CountDownTimer {

    public TextView tv1; //TODO: make setters instead of public
    public TextView tv2; //TODO: make setters instead of public

    public MyCountDownTimer(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
    }

    @Override
    public void onTick(long millisUntilFinished) {
        //Only use this if u have something to do each tick
        SimpleDateFormat df = new SimpleDateFormat(" dd,hh:mm:ss");
        Date timeRemaining = //TODO: figure out how you calculate your remaining time
        if(tv1 != null) {
            tv1.setText(df.format(timeRemaining));
        }
    }

    @Override
    public void onFinish() {
        if(tv1 != null && tv2!= null) {
            tv1.setText("Completion time over");
            tv2.setVisibility(View.GONE);
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33014999

复制
相关文章
【16】万恶的引导设计:配表篇
上一篇,我们了解了引导的一些理论知识,包括分段、分步的概念,强引导与弱引导,引导的触发、类别、操作、保存点等,本篇笔者将结合这些理论来聊聊引导的配表。
代码咖啡
2019/10/08
1K0
压测grafana面板之请求响应耗时解析
在某次压测护航中,有同学提问,为什么被压测服务后台日志查看到的大部分请求耗时都比95分位平均响应时间小?是不是数据统计的有问题?
cailynyu
2022/02/14
2.9K1
一个MySQL建表需求的讨论和引导
昨天收到一个业务同学的需求邮件,一般有些复杂的需求业务同学会发邮件告知我们,需要我们评估之后再做交付,我看了邮件之后,发现这个需求好像有点别扭,大体的意思是在中间件的环境中创建一张表,表结构如下:
jeanron100
2021/03/16
2.8K0
Bootstrap响应式前端框架笔记十五——面板与井
    Bootstrap中的面板由pannel相关类来创建,一个完整的面板分为面板头部、面板体和面板注脚,并且Bootstrap中默认定义了一些面板风格,示例如下:
珲少
2018/08/15
8000
Bootstrap响应式前端框架笔记十五——面板与井
【嘘】内有惊喜,请勿扩散
▼扫码加入DNSPod官方用户群▼ 第一时间追踪活动最新动态 SMB 腾讯云中小企业产品中心     腾讯云中小企业产品中心(简称SMB),作为腾讯云体系中唯一专业服务于8000万中小企业的业务线,致力于为中小微企业提供全面完善贴心的数字化解决方案。产品线覆盖了企业客户从创业起步期、规范治理期、规模化增长期、战略升级期等全生命周期,针对性的解决企业的信息化、数字化、智能化的生产力升级需求。本中心还拥有两大独立腾讯子品牌:DNSPod与Discuz!,在过去15年间,为超过500万企业级客户提供了强大、优质
腾讯云DNSPod团队
2022/01/21
2610
苦逼的程序员(内有惊喜)
很多人拿程序员来开涮,比如: 从前,有一个程序员,他临死的时候, 不小心得到了一盏神灯 。然后他向神灯许愿, 希望在有生之年能写一个好项目。 后来,后来他得到了永生。 再比如: 程序员职业服装! 还
用户1631416
2018/04/12
6030
苦逼的程序员(内有惊喜)
动手练一练,做一个响应式的后台管理面板
作为一名前端开发者,我们或多或少都会接触后台管理系统的制作,你是否会亲自纯手工制作做还是从网上找源码改一个呢?今天我们将从零开始纯手工制作一个后台管理面板的首页,通过这个案例你将会学习到如何制作一个响
前端达人
2020/03/16
1.3K0
动手练一练,做一个响应式的后台管理面板
千万级数据表选错索引导致的线上慢查询事故
又和大家见面了!又两周过去了,我的云笔记里又多了几篇写了一半的文章草稿。有的是因为质量没有达到预期还准备再加点内容,有的则完全是一个灵感而已,内容完全木有。羡慕很多大佬们,一周能产出五六篇文章,给我两个肝我都不够。好了,不多说废话了...
Rude3Knife的公众号
2020/08/02
1.4K0
国内有哪些好的刷题网站?
CoderAfterWork靠写代码挣钱去浪... 刷题也就这么点地方 1、Leetcode 鼎鼎大名的Leetcode,据不完全统计在上面被刷过的题可以围绕地球三圈。(没说赤道哈,就是这么严谨。)总之,很多国内外的码农在上面刷题。难度从easy到hard都有,而且覆盖面极广。现在还增加了数据库和shell,相匹配的论坛也可以多看看。很锻炼和国外码农沟通的能力,对于以后去混Github也有好处。 特点:各种语言支持很广泛,题型覆盖很广,测试数据集较弱。 2、Codility 同样一家著名的国外刷题网站。和L
前朝楚水
2018/04/04
3.4K0
Grafana 统计面板与文本面板的使用
统计面板可以用于显示一个大的统计值和一个可选的背景颜色,我们可以使用阈值来控制背景或颜色值,效果如下所示:
我是阳明
2021/11/23
2.6K0
MongoDB 路由表刷新导致响应慢场景解读
MongoDB sharding 实例从3.4版本升级到 4.0版本 以后插入性能明显降低,观察日志发现大量的 insert 请求慢日志:
MongoDB中文社区
2020/11/11
2K0
MongoDB 路由表刷新导致响应慢场景解读
2018,新年快乐 | 内有福利
长按二维码关注 “腾讯乐享” 随机送出20个QQ公仔 福利
腾讯乐享
2019/03/12
1.3K0
2018,新年快乐 | 内有福利
面板环境的安装
安装完成在浏览上打开面板的地址,登入面板,面板会自动推荐你安装环境套件,这里有两种选择,第一种是LNMP套件,第二种是LAMP套件:
霹格软件
2018/09/11
6540
面板环境的安装
cPanel面板和宝塔面板区别
  cPanel面板和宝塔面板有什么区别?cPanel面板和宝塔面板都是一种目前比较常用的服务器管理面板,那么,cPanel面板和宝塔面板哪个好呢?让我们一起来详细了解一下cPanel面板和宝塔面板吧
会长君
2023/04/26
4.2K0
清除linux系统的多余引导
由于我把系统给升级(update)了,在grub引导模式出现新旧版本(Grub与Grub2)的引导系统分别为正常启动和进入恢复模式各2个引导项,如下图显示:百度找不到相关或类似的教程,只好半夜起来研究,现在做好了并写下笔记。
用户1685462
2021/07/23
6.3K0
利用threshold实现的遮罩引导
点击“开始引导”,则进入引导操作。除指定的按钮可以操作外,其它区域均不可点击。这种应用当新功能或是新产品上线后,用来引导用户来使用产品/功能,是十分有用的。facebook也有类似的引导,方法也很简单:用4个绝对定位的DIV(指定一个背景 + 一定透明度)遮住其它部分,这样可以被操作的区域就“留空”出来。
meteoric
2018/11/16
6160
Netty中的引导类Bootstrap
Bootstrap是用来组织Netty的各个结构(pipeline,handler,eventloop),并使他们运行起来的类结构。分成两块,一个是客户端引导类Bootstrap,只用1个channel来处理所有的网络交互,另一个是服务端的ServerBootstrap,它提供一个父channel来接受客户端的请求,然后父channel创建多个子channel来用于的通信
爬蜥
2019/07/09
9560
旁观者.个性引导页个性引导页
这款个人主页简约而不失优雅,背景图片为随机api,共有38张随机图片,每次刷新都会看到不一样的美图。
小化先森
2023/03/05
1.1K0
点击加载更多

相似问题

这个单元测试是否与实现紧密耦合?

30

逻辑与数据紧密耦合的单元测试系统

40

不耦合到实现细节的单元测试行为

20

共享数据库与紧耦合消息模型

10

如何将此耦合应用程序解耦?

40
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文