1,
RecyclerView封装
2.使用databinding的recycleview的adapter封装
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/common_black_back" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"> <ImageView android:id="@+id/iv_back" android:layout_width="?attr/actionBarSize" android:layout_height="?attr/actionBarSize" android:layout_centerVertical="true" android:scaleType="centerInside" android:src="@drawable/ic_action_back" android:visibility="visible" /> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="相似K线" android:textColor="@android:color/white" android:textSize="20sp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="8dp" android:paddingBottom="8dp" android:background="@color/black" android:focusableInTouchMode="true" android:paddingLeft="10dp" android:paddingRight="10dp"> <EditText android:id="@+id/et_search" android:layout_width="match_parent" android:layout_height="28dp" android:layout_centerVertical="true" android:background="@drawable/ai_search_et_bg" android:hint="股票名称/代码/首字母" android:lines="1" android:paddingLeft="40dp" android:textColor="@color/quote_ai_text_blue" android:textColorHint="@color/quote_ai_text_blue" android:textSize="16sp" /> <ImageView android:layout_width="15dp" android:layout_height="15dp" android:layout_centerVertical="true" android:layout_marginLeft="15dp" android:src="@drawable/ic_ai_search_blue" /> </RelativeLayout> <com.dx168.efsmobile.widgets.MerchantWebView android:id="@+id/wv_kline" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
4.out T 等价于? extends T in T 等价于 ? super T 此外, 还有 * 等价于?
f:List<>,当F <| C 时, 如果有f(F) <| f(C),那么f叫做协变(Convariant); 当F <| C 时, 如果有f(C) <| f(F),那么f叫做逆变(Contravariance)。
如果上面两种关系都不成立则叫做不可变。
协变和逆协变都是类型安全的。
PECS
现在问题来了:我们什么时候用extends什么时候用super呢?《Effective Java》给出了答案:
PECS: producer-extends, consumer-super
Java中泛型是不变的,可有时需要实现逆变与协变,怎么办呢?这时就需要使用我们上面讲的通配符
?
。
<? extends T>
实现了泛型的协变
<? super T>
实现了泛型的逆变
泛型函数与其所在的类是否是泛型没有关系。泛型函数独立于其所在的类。我们应该尽量使用泛型方法,也就是说如果使用泛型方法可以取代将整个类泛型化,那么就应该只使用泛型方法,因为它可以使事情更明白。
5.
在 Kotlin 当中有一个关键字叫做 reified
,还有一个叫做 inline
,后者可以将函数定义为内联函数,前者可以将内联函数的泛型参数当做真实类型使用,我们先来看例子:
inline fun <reified T> Gson.fromJson(json: String): T{
return fromJson(json, T::class.java)
}
这是一个 Gson 的扩展方法,有了这个之后我们就无须在 Kotlin 当中显式的传入一个 class 对象就可以直接反序列化 json 了。
这个会让人感觉到有点儿迷惑,实际上由于是内联的方法调用,T 的类型在编译时就可以确定的:
class Person(var id: Int, var name: String)
fun test(){
val person: Person = Gson().fromJson("""{"id": 0, "name": "Jack" }""")
}
反编译之后:
public static final void test() {
Gson $receiver$iv = new Gson();
String json$iv = "{\"id\": 0, \"name\": \"Jack\" }";
Person person = (Person)$receiver$iv.fromJson(json$iv, Person.class);
}
注意,在这里,inline 是必须的。
6.单例
饿汉式单例
java实现
public class PlainOldSingleton { private static PlainOldSingleton INSTANCE = new PlainOldSingleton(); private PlainOldSingleton(){ System.out.println("PlainOldSingleton"); } public static PlainOldSingleton getInstance(){ return INSTANCE; } }
kotlin实现
object PlainOldSingleton {
}
非线程安全的懒汉式单例
java实现
public class LazyNotThreadSafe { private static LazyNotThreadSafe INSTANCE; private LazyNotThreadSafe(){} public static LazyNotThreadSafe getInstance(){ if(INSTANCE == null){ INSTANCE = new LazyNotThreadSafe(); } return INSTANCE; } }
kotlin实现
class LazyNotThreadSafe { companion object{ val instance by lazy(LazyThreadSafetyMode.NONE) { LazyNotThreadSafe() } //下面是另一种等价的写法, 获取单例使用 get 方法 private var instance2: LazyNotThreadSafe? = null fun get() : LazyNotThreadSafe { if(instance2 == null){ instance2 = LazyNotThreadSafe() } return instance2!! } } }
线程安全的懒汉式单例
java实现
public class LazyThreadSafeSynchronized { private static LazyThreadSafeSynchronized INSTANCE; private LazyThreadSafeSynchronized(){} public static synchronized LazyThreadSafeSynchronized getInstance(){ if(INSTANCE == null){ INSTANCE = new LazyThreadSafeSynchronized(); } return INSTANCE; } }
kotlin实现
class LazyThreadSafeSynchronized private constructor() { companion object { private var instance: LazyThreadSafeSynchronized? = null @Synchronized fun get(): LazyThreadSafeSynchronized{ if(instance == null) instance = LazyThreadSafeSynchronized() return instance!! } } }
DoubleCheck
java实现
public class LazyThreadSafeDoubleCheck { private static volatile LazyThreadSafeDoubleCheck INSTANCE; private LazyThreadSafeDoubleCheck(){} public static LazyThreadSafeDoubleCheck getInstance(){ if(INSTANCE == null){ synchronized (LazyThreadSafeDoubleCheck.class){ if(INSTANCE == null) { //初始化时分为实例化和赋值两步, 尽管我们把这一步写成下面的语句, // 但Java虚拟机并不保证其他线程『眼中』这两步的顺序究竟是怎么样的 INSTANCE = new LazyThreadSafeDoubleCheck(); } } } return INSTANCE; } }
kotlin实现
class LazyThreadSafeDoubleCheck private constructor(){ companion object{ val instance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){ LazyThreadSafeDoubleCheck() } private @Volatile var instance2: LazyThreadSafeDoubleCheck? = null fun get(): LazyThreadSafeDoubleCheck { if(instance2 == null){ synchronized(this){ if(instance2 == null) instance2 = LazyThreadSafeDoubleCheck() } } return instance2!! } } }
静态内部类单例
java实现
public class LazyThreadSafeStaticInnerClass { private static class Holder{ private static LazyThreadSafeStaticInnerClass INSTANCE = new LazyThreadSafeStaticInnerClass(); } private LazyThreadSafeStaticInnerClass(){} public static LazyThreadSafeStaticInnerClass getInstance(){ return Holder.INSTANCE; } }
kotlin实现
class LazyThreadSafeStaticInnerObject private constructor(){ companion object{ fun getInstance() = Holder.instance } private object Holder{ val instance = LazyThreadSafeStaticInnerObject() } }