日常学到的关于Android小知识

这个就用来当做日常记录的新知识就行了, 一些小知识,如果单开一篇Blog会很耗时间,所以就以这种方式来记录了

Widget

ViewHolder的作用:

当使用listView的时候,由于使用mvp框架,所以就必须用到adapter,但是当滑动的时候,如果adapter 的item过多的话,就会导致系统每次加载布局的时候,都重新加载一次,代码如下(因为adapter是使用getView来加载页面布局的,所以就只显示getview):

第一种方法:

public View getView(int position,View convertView,ViewGroup parent)
			convertView= LayoutInflater.inflate(R.layout.item,parent,false);
            TextView textView=(TextView) convertView.findViewById(R.id.nText);
            ImageView imageView=(ImageView)convertView.findViewById(R.id.iconImg);
            textView.setText(mData[position].getName);
            imageView.setImageResource(mData[position].getIcon);
            return convertView;
}

上面的代码过于重复,即每次当加载一个新的item的时候,都会重新构造一次convertView,所以就导致了复用性很差。

第二种方法

public View getView(int position,View convertView,ViewGroup parent)
		if(convertView==null){
			convertView= LayoutInflater.inflate(R.layout.item,parent,false);
			}
            TextView textView=(TextView) convertView.findViewById(R.id.nText);
            ImageView imageView=(ImageView)convertView.findViewById(R.id.iconImg);
            textView.setText(mData[position].getName);
            imageView.setImageResource(mData[position].getIcon);
            return convertView;
}

第二种方法,比第一种稍微好点,就是因为只有在convertView为空的时候,才回去重新加载convertView,所以导致converView的重复利用性稍微好点。但是每次还是会去找findViewById()这样也会导致效率比较低。

第三种方法

public View getView(int position,View convertView,ViewGroup parent){
		ViewHolder holder;
		if(convertView==null){
			convertView= LayoutInflater.inflate(R.layout.item,parent,false);
			holder=new ViewHolder;
			holder.textView=(TextView)convertView.findViewById(R.id.nText);
			holder.imageView=(ImageView)convertView.findViewById(R.id.iconImg);
			convertView.setTag(holder)}
			else{
			holder=convertView.getTag();
			}
			holder.textView.setText=(mData[position].getName);
			holser.iamgeView.setImageResource(mData[position].getIcon);
			return convertView;
}

static class Viewholder{
	private TextView textView;
	private ImageView imageView;
}

所以从以上可以看出来,holder的主要作用就是为了convertView中的item的元素的与convertView直接绑定,然后封装到holder里面,这样就不用每次都从convertView里面找了。
所以通俗来说,hoder的作用就两个:1、绑定item里面的view元素 2、设置item里面的view元素的值。

Alert 中的按键,点击无响应:

问题描述 在alert里面自己设置了三个按键,但是最后点击的时候没有反应。

错误做法:最后发现原来是在MainActivity里面我设置了五个按键,最开始设置的就单纯地设置alert里面id来设置时间,但是最后发现这个方法是错误的。

正确做法: 先用LayoutInflat.inflater() 的方法把自己设置的alert实例化出来,然后通过.findViewById(),将按键初始化,最后,通过设置setOnClickListener()来设置监听器。
代码如下:

View view_alert = LayoutInflater.from(mContext).inflate(R.layout.view_dialog_custom, null, false);                     Builder builder = new AlertDialog.Builder(mContext);
builder.setView(view_alert);
builder.setCancelable(false);
alertDialog = builder.create();
             view_alert.findViewById(R.id.btn_dialog_confirm).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Uri uri = Uri.parse("https://www.58pic.com/");
                        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                        startActivity(intent);
                        alertDialog.dismiss();
                    }
                });
                view_alert.findViewById(R.id.btn_dialog_cancel).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        midToast("你取消了观看,真是个好孩子!", 0);
                        alertDialog.dismiss();
                    }
                });
                view_alert.findViewById(R.id.btn_dialog_close).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        alertDialog.dismiss();
                    }
                });
                alertDialog.show();

ViewPager 不显示

最开始的时候,以为是直接在ManiActivity里面直接创建viewpager就行,但是最后的时候发现,无论这么惦记,都不显示,最后找到了个还不错的方法。(新创建一个活动,Activity_one )然后在这个活动里面过构造viewpager,然后再主方法中intent到活动1就行,大概方法就是这样的。代码如下

这是在Aciticity_one.java里的代码。

public class Activity_one extends AppCompatActivity {
    private ViewPager vpager_one;
    private ArrayList<View> aList;
    private MyPagerAdapter mAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_one);
        vpager_one = (ViewPager) findViewById(R.id.vpager_one);

        aList = new ArrayList<View>();
        LayoutInflater li = getLayoutInflater();
        aList.add(li.inflate(R.layout.view_one,null,false));
        aList.add(li.inflate(R.layout.view_two,null,false));
        aList.add(li.inflate(R.layout.view_three,null,false));
        mAdapter = new MyPagerAdapter(aList);
        vpager_one.setAdapter(mAdapter);
    }
}

这是在avtivity_one.xml的代码

<?xml version="1.0"?>

    <LinearLayout tools:context=".MainActivity" android:orientation="vertical" android:layout_height="match_parent" android:layout_width="match_parent" android:id="@+id/LinearLayout1" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView android:layout_height="48dp" android:layout_width="match_parent" android:textStyle="bold" android:textColor="#000000" android:textSize="18sp" android:text="简单的ViewPager使用" android:gravity="center" android:background="#FFC3AB"/>

    <androidx.viewpager.widget.ViewPager android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/vpager_one" android:layout_gravity="center"/>

</LinearLayout>

在MainActivity.java里面的代码(MyPagerAdaper代码就不贴了,就是继承PagerAdaper代码,重写里面的方法。)

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


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

        Button button=findViewById(R.id.btn_mian_vigor);
        button.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        startActivity(new Intent(this,Activity_one.class));
    }
}

Notification 遇到了Bad notification for startForeground

这段时间想用notification来在前台显示一个notification,但是当运行的时候,却出现了Bad notification for startForeground的情况,所以就在网上找了方法。
第一:需要在AndroidMinifest.xml中声明使用权限。

第二步:这时候需要在创建notification的时候,使用到新的方法来创建,比如在:notification中使用notificationchannel的方法
reference:

  	@Override
    public void onCreate() {
        super.onCreate();
        //注册一个notificationchannel,并且设置他的name和id。
        NotificationChannel channel=new 	  		NotificationChannel("channel_one","channel_name",NotificationManager.IMPORTANCE_HIGH);
        NotificationManager manager=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.createNotificationChannel(channel);
        //build notification
        Notification.Builder localBuilder = new Notification.Builder(this);
        localBuilder.setChannelId("channel_one");
        localBuilder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0));
        localBuilder.setAutoCancel(false);
        localBuilder.setSmallIcon(R.mipmap.ic_launcher);
        localBuilder.setTicker("Foreground Service Start");
        localBuilder.setContentTitle("Socket服务端");
        localBuilder.setContentText("正在运行...");
        startForeground(1, localBuilder.build());
    }

Handler构造方法过期

原本今天想试下新的handler的构造方法,但是最后试出来的时候,发现自己

Handler handler=new Handler()
	{
		}

被弃用了,看源代码也没看明白,所以就找了半天,最后找到了解决方法

Handler handler=new Handler(Looper.getMainLooper)
	{
		}

这里只适用于在主线程里面的handler,因为主线程已经有handler了,如果是其他线程,那就老老实实Looper.prepare()和looper.loop();(一个小知识点)

Flutter踩坑笔记

BlendMode运行无效

吐槽下,但是由于要运用到开发跨平台平台开发,虽然Flutter可读性太差,但是只能这么使用了。

学习了blend之后,然后无论怎么运行都无效,最后发现BlendMode必须搭配颜色使用:reference:

child:Image.network(
              "https://picsum.photos/250?image=9",
              alignment: Alignment.topCenter,
              color: Colors.blue,//注意这一步少了的话就会导致BlendMode失效
              colorBlendMode:BlendMode.screen
            ),

其他问题

IntentService中的Toast无法显示

当想在IntentService中使用Toast的时候,会发生无法显示的问题。reference:

@Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Toast.makeText(this,"Hello world",Toast.LENGTH_LONG).show();
    }

但是在主界面无法显示,最后百度发现问题,这是因为intent相当于开了个新的线程,所以就必须要用到Hanlder.post();

解决方案:

@Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Handler handler=new Handler(Looper.getMainLooper());
        handler.post(new Runnable(){
            public void run(){
                //your operation...
                Toast.makeText(getApplicationContext(), "hello world", Toast.LENGTH_SHORT).show();
            }
        });
    }

android 里的outer:

今天学习handler的时候,发现了这个问题,在ui子线程低于某数的全部质数,学的时候发现个东西,源码里面有一个outer:不知道是个啥,百度了也没有,最后发现原来来相当于java中的goto:
代码如下:

outer:
      for (int i =2;i<=upper;i++) {
        for (int j=2;j<=Math.sqrt(i);j++){
      	 if (i!=2 && i%j==0){
  		      continue outer;
			      }
	                 }
          nums.add(i);
                }

如果没有这个outer的话,那么这里就会出现当里层for循环判断为true的时候,不会直接跳出来,所以打个标签,当里层判断为true的时候,直接判断为false,直接开始下一个循环。这是多于多层循环直接跳到某个循环的方法。

lambda表达式

lambda表达式是JDK8的新特性,以前有接触过,但是一直没有详细的学,今天在学到遍历的时候又用到了这个方法,所以就看了下别的大佬的博客,懂了个大概,以后就在实践中慢慢摸索就行。
lambda主要是为了简化代码,主要是实现匿名内部类的方法,用以实现接口的方法:reference:

public interface Customer{
	void getItem();
}
......
public static void main(){
	Customer cus=new Customer(()->return 1);//前面的小括号写该抽象方法的参数,类型可以省略,箭头后面写该方法的方法体,如果该方法只有一行方法体,可以按照以上方法省略花括号,也可以省略return,我这没省略是为了让自己理解。
	}

如果还有不明白的,推荐这个博主的文章,写的很好:https://www.cnblogs.com/haixiang/p/11029639.html

Dart的list.map作用

虽然这个不是安卓原生开发问题,但是作为跨平台,也和安卓有点关系,所以就写到这里来了。

  List<int> l1 = [8, 12, 4, 6, 22, 34, 10];
  Iterable<bool> l2 = l1.map((e) => e > 10);//小括号里面的是参数,后面的是返回的内容,返回的是布尔类型。
  Iterable<String> l3 = l1.map((e) => e > 10 ? "大" : "小");//这里后面时候三目运算符没啥说的。
  Iterable<num> l4 = l1.map((e) => e > 12 ? e / 2 : e * 2);
  print(l2); // (false, true, false, false, true, true, false);
  print(l3); // (小, 大, 小, 小, 大, 大, 小);
  print(l4); // (16, 24, 8, 12, 11.0, 17.0, 20);

这里引用了这位 博主的文章,写的很详细,https://blog.csdn.net/qq_42351033/article/details/107924344

Flutter 中Aspecratio图片不能适配比例

本来看课程老师说的aspecraio可以按照自己设置的比率来适配图片,但是最后的时候发现毛事出现了点问题,是适配不来,网上也没有详细解答,最后通过看一位博主的文章发现了解决方法。reference:

Widget build(BuildContext context) {
    return Container(
      width: 300.0,
      child: AspectRatio(aspectRatio: 1.0 / 1.0,
          child: Image.network(
              "https://pics6.baidu.com/feed/4ec2d5628535e5ddd7769ccbe75f1ce8cf1b62e8.jpeg?token=9b2c78e4d5b123db8f099fb55b2081b7&s=0E406A8613628B513CF9653D0300E042",),
    );

无论这么展示,都只是原来的图片的适配比,最后的时候发现了端倪:主要是没有设置图片的适配方式fit
当加上之后,就会出现图片会改变自己的比率:reference

Widget build(BuildContext context) {
    return Container(
      width: 300.0,
      child: AspectRatio(aspectRatio: 1.0 / 1.0,
          child: Image.network(
              "https://pics6.baidu.com/feed/4ec2d5628535e5ddd7769ccbe75f1ce8cf1b62e8.jpeg?token=9b2c78e4d5b123db8f099fb55b2081b7&s=0E406A8613628B513CF9653D0300E042",
          fit: BoxFit.cover,),),
    );

flutter动态加载列表元素

在flutter 中动态加载列表元素,主要是以下代码有几个容易犯错的地方,这里着重强调下reference:

class _LayoutDemoState extends State<LayoutDemo> {
  List list = new List();
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [			
        Column(					//这里的Column必须需要,因为这里的如果直接在外面返回ListTile会显示不能将列表作为组件,表明了在ListView中的children只能是组件,而在column中的child不一定是组件。
            children: this.list.map((value) {
          return ListTile(
            title: Text(value),
          );
        }).toList()),	//这里的tolist虽然老师上课的时候一直在讲解,但是由于我没有经常用,导致写的时候有点遗忘。
        MyButton(
          "多多",
          onPressed: () {
            setState(() {	//如果要想改变组件状态就必须添加上这个股setState里面修改,不然不会修改。
              list.add("我是一条数据1");
              list.add("我是一条数据2");
            });

          },
        )
      ],
    );
  }
}

Dart构造函数的语法

虽然已经学了Dart,但是有dart和java的语法还是有点差别,所以说当看见dart的简单构造方法还是很懵逼。

class Point {
  num x, y;

  // Syntactic sugar for setting x and y
  // before the constructor body runs.
  Point(this.x, this.y);
}

比如这样构造函数,然让给人摸不着头脑,其实这个构造函数是这个下面的构造函数的省略方式:reference:

class Point {
  num x, y;

  Point(num x, num y) {
    // There's a better way to do this, stay tuned.
    this.x = x;
    this.y = y;
  }
}

这是dart的语法糖。

flutter中的padding

今天使用flutter的时候,设置了padding,最后发现padding无效,我把padding放在了center里面,让他当做center的属性,但是无论这么设置最后的结果都无效,最后将padding放到了container里面,当做container的子类,才有效果。(一个小知识点)

结语

本文会长期更新,如果是一些大的知识点会开新blog,一些小知识点会在这更新,当做自己的笔记本,如果能顺便帮助你,那就最好不过了。

最后一次更新:15/12/2020

世界上只有一种真正的英雄主义,那就是看清了生命的真相,并且任然热爱它。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值