我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解Android Checkbox的使用方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解Android Checkbox的使用方法

0和1是计算机的基础,数理逻辑中0和1代表两种状态,真与假.0和1看似简单,其实变化无穷. 今天我就来聊聊android控件中拥有着0和1这种特性的魔力控件checkbox.

先来讲讲Checkbox的基本使用.在XML中定义.


<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/cbx"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:checked="false" />

在Activity中使用


CheckBox cbx = (CheckBox) findViewById(R.id.cbx);
cbx.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  @Override
  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   //do something
  }
});

很简单.要注意的是,CheckBox本身是一个视图,是展示给用户看的,因此我们要用数据来控制它的展示.所以,我们的CheckBox在Activity中要这么写


boolean isChecked= false;
CheckBox cbx = (CheckBox) findViewById(R.id.cbx);
cbx.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  @Override
  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if(isChecked){
      //do something
    }else{
      //do something else
    }
  }
});
cbx.setChecked(isChecked);

这样,我们改变数据的时候,视图的状态就会跟着数据来做改变了.注意,监听器一定要这setChecked之前设置,这样才能体现出来数据来控制视图的展示.

单独用CheckBox很easy,接下来,复杂的情况来啦,CheckBox如何跟ListView/RecyclerView(以下简称LV/RV)配合使用.这就不能简单的考虑问题啦,要知道LV/RV中的视图个数跟数据集的里面的数据并不一致,真正的视图个数远小于数据集中数据项的个数.因为屏幕上在列表中的视图是可以复用的.由于LV/RV的复用机制,如果我们没有用数据来控制CheckBox状态的话,将会导致CheckBox的显示在列表中错乱.比方说你只对第一个Item中的CheckBox做了选中操作,当列表向上滚动的时候,你会发现,下面的Item中居然也会有被选中的.当然,我刚学Android时候也遇到过这种情况,问题的关键就在于要用数据来控制视图的显示.因此在getView/onBindViewHolder中,我们应该这么写.


holder.cbx.setTag(item);
holder.cbx.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  @Override
  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    Item item =(Item) buttonView.getTag();
    if(isChecked){
      item.setCheckState(true);
      //do something
    }else{
      item.setCheckState(false);
      //do something else
    }
  }
});
cbx.setChecked(item.getCheckState());

这种方法基本正确,但是我们要额外的给每个数据项里面添加一个字段来记录状态,这代价就有点大了.一是不必这么做,二是这会导致本地数据结构跟服务端结构不一致.通常,列表中使用CheckBox的话,很明显是把选中的item给记录下来,可以这么理解,选中的状态是列表给的,而item本身应该是无状态的.那么,如果重构我们的代码呢,Android为我们提供了一种完美的数据结构来解决这个问题.你可以用SparseArray,也可以用SparseBooleanArray,我现在习惯使用SparseBooleanArray,ok,请看代码


private class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
  SparseBooleanArray mCheckStates=new SparseBooleanArray();
  @Override
  public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    //...
  }
  @Override
  public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    holder.cbx.setTag(position);
    holder.cbx.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
      @Override
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        int pos =(int)buttonView.getTag();
        if(isChecked){
          mCheckStates.put(pos,true);
          //do something
        }else{
          mCheckStates.delete(pos);
          //do something else
        }
      }
    });
    cbx.setChecked(mCheckStates.get(position,false));
  }
  @Override
  public int getItemCount() {
    //...
  }
}

这样列表就能正常显示了,而且在你选中CheckBox的时候,会自动触发onCheckedChanged来对mCheckStates来进行更新.此时,如果你想用程序来选中某个item的时候,那么直接这样就行了.


mCheckStates.put(pos,true);
adapter.notifyDatasetChanged();

如果我们想要取出列表列中所有的数据项,那么有了SparseBooleanArray,这个就非常好办啦.


ArrayList<Item> selItems=new ArrayList<>();
for(int i=0;i < mCheckStates.size();i++){
  if(mCheckStates.valueAt(i)){
    selItems.add(allItems.get(mCheckStates.keyAt(i)));
  }
}

竟然是如此的节省空间和时间,这样的代码谁不喜欢呢.但是,这还不完美. 由于CheckBox这个控件太容易变了,为什么这么说呢,因为就算你把它设成disabled的话,它依然是可以点选的,它的onCheckedChanged依然会触发.那么我们该怎么办呢.程序员考虑问题呢,一般都是先想最笨的方法啦,既然onCheckedChanged依然会触发,那我就在里面把buttonView再设置成!isCheck的不就行了嘛.


holder.cbx.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  @Override
  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    buttonView.setChecked(!isChecked);
    //...
  }
});

但是这么写的话,就会调用buttonView的onCheckedChanged,其实buttonView就是外面的holder.cbx,这就会造成死循环.因此我们如果用cbx本身去改变状态的话,那么一定要加锁.


boolean lockState=false;
holder.cbx.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  @Override
  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
   if(lockState)return;
   //不然cbx改变状态.
   lockState=true;
    buttonView.setChecked(!isChecked);
    lockState=false;
    //...
  }
});

对cbx加锁其实还是挺常用的,比方说在onCheckedChanged中,你要发一个请求,而请求的结果反过来会更新这个cbx的选中状态,你就必须要用lockState来直接改变cbx的状态了,以便于cbx的状态跟mCheckStates里面的是一致的.

mada mada,还有一种情况,如果在onCheckedChanged的时候,isChecked跟mCheckStates.get(pos)一致的话,这会导致什么情况呢.


@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
 int pos =(int)buttonView.getTag();
  if(isChecked){
 mCheckStates.put(pos,true);
   //do something
 }else{
   mCheckStates.delete(pos);
   //do something else
 }
}

这就会让你的//do something做两次,这么做就是没有必要的啦,而且如果你的//do something是网络请求的话,这样就会导致更大问题.所以,我们有必要对这种情况做过滤.


@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  if(lockState)return;
  int pos =(int)buttonView.getTag();
  if(mCheckStates.get(pos,false) == isChecked)return;
  if(isChecked){
   mCheckStates.put(pos,true);
   //do something
  }else{
   mCheckStates.delete(pos);
   //do something else
  }
}

好啦,如果你能将CheckBox跟SparseBooleanArray联用,并且能考虑到加锁和过滤重选的话,那么说明你使用CheckBox的姿势摆正了.但是,我要讲的精彩的地方才刚刚开始.

一个列表仅仅能让用户上滚下滑,那是最简单的使用,通常,由于列表项过多,产品会给列表项添加筛选的功能,而通常我们做筛选,会考虑到使用Spinner来做,但是,有用android自身提供的Spinner扩展性太差,而且长得丑,往往导致大家一怒之下,弃而不用.我呢,就是这么干的.经过本人的奇思妙想,本人终于找到了一种很巧妙的机制来很优雅的实现列表的筛选.下面我就来给大家分享一下.

接下来清楚我们今天的另一位主角,那就是PopupWindow(介绍),我先介绍一下原理,首先给CheckBox设置setOnCheckedChangeListener,然后在onCheckedChanged里面,isChecked分支中弹出PopupWindow,!isChecked中,读取Popupwindow中的结果,用新的筛选条件来更新列表.ok,上代码:

MainActivity:


public class MainActivity extends AppCompatActivity {
  String[] filter_type_strs = {"音乐", "书籍", "电影"};
  CheckBox cbx;
  private boolean lockState=false;
  int current_filter_type=0;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    cbx = (CheckBox) findViewById(R.id.cbx);
    cbx.setText(filter_type_strs[current_filter_type]);
    cbx.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
      @Override
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (lockState) return;
        try {
          if (isChecked) {
            //此处传入了cbx做参数
            PopupWindow pw = new FilterLinePw(buttonView.getContext(), cbx, filter_type_strs);
            pw.showAsDropDown(cbx);
          } else {
            //此处的buttonView就是cbx
            Integer pos = (Integer) buttonView.getTag();
            if (pos == null || pos == -1) return;
            current_filter_type = pos;
            Toast.makeText(MainActivity.this, "搜索"+filter_type_strs[current_filter_type], Toast.LENGTH_SHORT).show();
          }
        } catch (NullPointerException e) {
          //以防万一
          lockState = true;
          buttonView.setChecked(!isChecked);
          lockState = false;
        }
      }
    });
  }
}

FilterLinePw:


public class FilterLinePw extends PopupWindow {
  RadioGroup radioGroup;
  CheckBox outCbx;
  //为动态生成radioButton生成id
  int[] rbtIds = {0, 1, 2};
  public FilterLinePw(Context context, CheckBox outCbx, String[] items) {
    super(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    View contentview = LayoutInflater.from(context).inflate(R.layout.filter_line_popupwindow, null);
    setContentView(contentview);
    setFocusable(true);
    setOutsideTouchable(true);
    this.outCbx = outCbx;
    contentview.setOnKeyListener(new View.OnKeyListener() {
      @Override
      public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
          dismiss();
          return true;
        }
        return false;
      }
    });
    contentview.setFocusable(true); // 这个很重要
    contentview.setFocusableInTouchMode(true);
    contentview.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        dismiss();
      }
    });
    init(context, contentview,items);
  }
  private void init(Context context, View contentview, String[] items) {
    
    radioGroup = (RadioGroup) contentview.findViewById(R.id.filter_layout);
    radioGroup.clearCheck();
    if (items == null) return;
    for (int i = 0; i < items.length; i++) {
      RadioButton radioButton = (RadioButton) LayoutInflater.from(context).inflate(R.layout.line_popupwindow_rbt, null);
      radioButton.setId(rbtIds[i]);
      radioButton.setText(items[i]);
      radioGroup.addView(radioButton, -1, radioGroup.getLayoutParams());
      if (items[i].equals(outCbx.getText())) {
        outCbx.setTag(i);
        radioButton.setChecked(true);
      }
    }
    radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
      @Override
      public void onCheckedChanged(RadioGroup group, int checkedId) {
        dismiss();
      }
    });
  }
  //重点内容,重写dismiss();
  @Override
  public void dismiss() {
    if (outCbx != null && outCbx.isChecked()) {
      int id = radioGroup.getCheckedRadioButtonId();
      RadioButton rbt = (RadioButton) radioGroup.findViewById(id);
      Integer old_tag = (Integer) outCbx.getTag();
      if (old_tag == null) {
        super.dismiss();
        return;
      }
      if (old_tag != id) {
        outCbx.setTag(id);
        outCbx.setText(rbt.getText());
      } else {
        outCbx.setTag(-1);
      }
      //下面执行之后,会执行MainActivity中的onCheckedChanged里的否定分支
      outCbx.setChecked(false);
    }
    super.dismiss();
  }
}

效果图:

简单解释一下:其实重点在PopupWindow里面,MainActivity的CheckBox作为参数传递到了 PopupWindow里.首先,用户点击MainActivity的CheckBox,接着会执行isChecked分支,这样PopupWindow就展示给了用户,这样用户操作的环境就到了PopupWindow里面,等用户选择好筛选条件后,PopupWindow就把筛选条件设给outCbx,然后改变outCbx状态,从而触发MainActivity中onCheckedChanged中的否定分支,此时展示的是一个Toast,实际应用中可以是一个网络请求.同时,由于PopupWindow的代码并没有阻塞操作,所以会接着执行下一句 super.dismiss(),这样你在MainActivity就不用担心PopupWindow的关闭问题啦.最后,在MainActivity中还加入了try-catch来以防万一,这种机制真是太神奇啦.这种机制把筛选操作从Activity中分离了出来,以后我们写筛选可以完全独立于Activity啦,真的是一种很软件工程的做法.

随后我会把其他筛选的情况开源,但是最精妙的原理就在于这个简单的例子上.各位看完之后不妨亲自动手试试,感受一下.

好啦,精彩的地方讲完了,是不是不过瘾啊.好吧,最后,我再拿点私房菜出来. CheckBox是继承自TextView,很多时候,我们的CheckBox的button属性设置的图片都不大,这就导致点击CheckBox的区域也小,因此,我们需要用到TouchDelegate来扩大CheckBox的可点击区域上代码:


public class FrameLayoutCheckBox extends FrameLayout {
  CompoundButton cbx;
  public FrameLayoutCheckBox(Context context) {
    super(context);
  }
  public FrameLayoutCheckBox(Context context, AttributeSet attrs) {
    super(context, attrs);
  }
  public FrameLayoutCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }
  private CheckBox findCheckBox(View view) {
    //无递归广度优先遍历寻找CheckBox - -!我只是想重温一下C
    ArrayList<View> views = new ArrayList<>();
    views.add(view);
    while (!views.isEmpty()) {
      View c = views.remove(0);
      if (c instanceof CheckBox) {
        return (CheckBox) c;
      } else if (c instanceof ViewGroup) {
        ViewGroup fa = (ViewGroup) c;
        for (int i = 0; i < fa.getChildCount(); i++) {
          views.add(fa.getChildAt(i));
        }
      }
    }
    return null;
  }
  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();
    if (getChildCount() > 0) {
      View child = findCheckBox(this);
      if (child instanceof CompoundButton) cbx = (CompoundButton) child;
    }
  }
  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    if (cbx != null) {
      Rect bounds = new Rect(getPaddingLeft(), getPaddingTop(), getPaddingLeft() + getMeasuredWidth() + getPaddingRight(), getPaddingTop() + getMeasuredHeight() + getPaddingBottom());
      TouchDelegate delegate = new TouchDelegate(bounds, cbx);
      setTouchDelegate(delegate);
    }
  }
}

这个类可以当成FrameLayout,我们可以把CheckBox放里面,然后CheckBox的点击区域就是整个FrameLayout的区域啦.当然这个类也适用于RadioButton,但是你不能放多个CompoundButton在里面。

您可能感兴趣的文章:Android RecycleView使用(CheckBox全选、反选、单选)Android中CheckBox复选框控件使用方法详解Android开发之CheckBox的简单使用与监听功能示例Android 中CheckBox多项选择当前的position信息提交的示例代码Android中ListView + CheckBox实现单选、多选效果Android实现炫酷的CheckBox效果Android中ListView绑定CheckBox实现全选增加和删除功能(DEMO)Android开发中CheckBox的简单用法示例Android中自定义Checkbox组件实例Android CheckBox中设置padding无效解决办法


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

详解Android Checkbox的使用方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

详解Android Checkbox的使用方法

0和1是计算机的基础,数理逻辑中0和1代表两种状态,真与假.0和1看似简单,其实变化无穷. 今天我就来聊聊android控件中拥有着0和1这种特性的魔力控件checkbox. 先来讲讲Checkbox的基本使用.在XML中定义.
2022-06-06

Android中CheckBox复选框控件使用方法详解

CheckBox复选框控件使用方法,具体内容如下一、简介1、2、类结构图二、CheckBox复选框控件使用方法这里是使用java代码在LinearLayout里面添加控件1、新建LinearLayout布局2、建立CheckBox的XML的
2023-05-30

Android 中CheckBox的isChecked的使用实例详解

Android 中CheckBox的isChecked的使用实例详解 范例说明所有的网络服务在User使用之前,都需要签署同意条款,在手机应用程序、手机游戏的设计经验中,常看见CheckBox在同意条款情境的运用,其选取的状态有两种即isC
2022-06-06

android RadioButton和CheckBox组件的使用方法

RadioButton是单选按钮,多个RadioButton放在一个RadioGroup控件中,也就是说每次只能有1个RadioButton被选中。而CheckBox是多选按钮,Toatst是android中带的一个用于显示提示小窗口消息的
2022-06-06

Android MVP模式ListView中嵌入checkBox的使用方法

MVP模式 ListView中嵌入checkBox的使用 本文写的是一个小demo,如何在ListView中嵌入checkBox配合使用,本篇文章与前面的嵌入Button类似,同样的采用MVP模式的写代码,本次案例中会有几个小细节,我将会在
2022-06-06

Android Notification 使用方法详解

Android Notification 使用方法详解用TaskStackBuilder来获取PendingIntent处理点击跳转到别的Activity,首先是用一般的PendingIntent来进行跳转。mBuilder = new N
2023-05-30

Android HandlerThread使用方法详解

Android HandlerThread使用方法详解HandlerThread 继承自Thread,内部封装了Looper。首先Handler和HandlerThread的主要区别是:Handler与Activity在同一个线程中,Han
2023-05-30

android BitmapFactory.Options使用方法详解

BitmapFactory.Options的使用是在加载图片时,就从图片的加载和使用说起 怎样获取图片的大小?首先我们把这个图片转成Bitmap,然后再利用Bitmap的getWidth()和getHeight()方法就可以取到图片的宽高
2022-06-06

Android Tabhost使用方法详解

Android 实现tab视图有2种方法,一种是在布局页面中定义标签,另一种就是继承tabactivity.但是我比较喜欢第二种方式,应为如果页面比较复杂的话你的XML文件会写得比较庞大,用第二种方式XML页面相对要简洁得
2022-06-06

android TabLayout使用方法详解

Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更
2022-06-06

Android IdleHandler使用方法详解

这篇文章主要为大家介绍了Android IdleHandler使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

详解Android中Handler的使用方法

在Android开发中,我们经常会遇到这样一种情况:在UI界面上进行某项操作后要执行一段很耗时的代码,比如我们在界面上点击了一个”下载“按钮,那么我们需要执行网络请求,这是一个耗时操作,因为不知道什么时候才能完成。为了保证不影响UI线程,所
2022-06-06

详解Android中IntentService的使用方法

为什么我们需要IntentService Android中的IntentService是继承自Service类的,在我们讨论IntentService之前,我们先想一下Service的特点: Service的回调方法(onCreate、o
2022-06-06

Android 使用View Binding的方法详解

前言 Android Studio稳定版发布了3.6版本,带来了一些新变化:首先外观,启动页变了,logo改了,更显现代化;增加Multi Preview功能,能同时预览多个尺寸屏幕的显示效果;模拟器支持多屏;也终于支持全新的视图绑定组件V
2022-06-07

Android 中Context的使用方法详解

Android 中Context的使用方法详解概要:Context字面意思是上下文,位于framework package的android.content.Context中,其实该类为LONG型,类似Win32中的Handle句柄。很多方法
2023-05-30

详解Android中Notification的使用方法

在消息通知的时候,我们经常用到两个控件Notification和Toast。特别是重要的和需要长时间显示的信息,用Notification最合适不过了。他可以在顶部显示一个图标以标示有了新的通知,当我们拉下通知栏的时候,可以看到
2022-06-06

详解Android中AsyncTask的使用方法

在Android中实现异步任务机制有两种方式,Handler和AsyncTask。Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但
2022-06-06

详解Android中weight的使用方法

android中对weight的学习可以说是必须的,如果UI布局仅仅使用dp与sp等等,会让布局显得极度不灵活,毕竟各个手机屏幕大小不同,更别说是还有ipad之类的了,所以也是同做本人近期做的一个小UI来分享一下weight的使用。
2022-06-06

详解Android中Intent的使用方法

一、Intent的用途 Intent主要有以下几种重要用途: 1. 启动Activity:可以将Intent对象传递给startActivity()方法或startActivityForResult()方法以启动一个Activity,该I
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录