Android开发日常笔记

如何在Android Studio添加本地aar包引用

如何在Android studio中,给android 项目添加外部lib引用。在android studio中,有两种方式:一种是jar包,一种是带资源文件的aar包,

  • jar: 只包含了class文件与清单文件 ,不包含资源文件,如图片等所有res中的文件。
  • aar: 包含jar包和资源文件,如图片等所有res中的文件

复制外部aar包到libs目录下,在build.gradle下添加依赖

apply plugin: 'com.android.application'

android {
    ...
}

repositories {
    flatDir {
        dirs 'libs'
    }
}
dependencies {
    compile (name:'libname',ext:'aar')
}

editplus文件编码批量转换

editplus全部打开之后(打开为何种编码不重要),选文档(Document)菜单 –>文件编码(File encoding) –> 批量转换编码(File encoding multiple),选中全部文件后转码,然后再全部保存

minSdkVersion、targetSdkVersion、maxSdkVersion、target API level四个数值到底有什么区别?

minSdkVersion与maxSdkVersion比较容易理解,就是在安装程序的时候,如果目标设备的API版本小于minSdkVersion,或者大于maxSdkVersion,程序将无法安装。一般来说没有必要设置maxSdkVersion。

targetSdkVersion相对复杂一些,如果设置了此属性,那么在程序执行时,如果目标设备的API版本正好等于此数值,他会告诉Android平台:此程序在此版本已经经过充分测,没有问题。不必为此程序开启兼容性检查判断的工作了。也就是说,如果targetSdkVersion与目标设备的API版本相同时,运行效率可能会高一些。但是,这个设置仅仅是一个声明、一个通知,不会有太实质的作用,比如说,使用了targetSdkVersion这个SDK版本中的一个特性,但是这个特性在低版本中是不支持的,那么在低版本的API设备上运行程序时,可能会报错:java.lang.VerifyError。也就是说,此属性不会帮你解决兼容性的测试问题。你至少需要在minSdkVersion这个版本上将程序完整的跑一遍来确定兼容性是没有问题的。

在default.properties中的target是指在编译的时候使用哪个版本的API进行编译。

综上,上面的四个值其实是作用于不同的时期:target API level是在编译的时候起作用,用于指定使用哪个API版本(SDK版本)进行编译。minSdkVersion和maxSdkVersion是在程序安装的时候起作用,用于指定哪些版本的设备可以安装此应用。targetSdkVersion是在程序运行的时候起作用,用于提高指定版本的设备上程序运行体验。这四个数值在程序编译时也没有严格的检查,比如说,你可以将minSdkVersion设置的比maxSdkVersion还大,他会自动忽略掉错误的maxSdkVersion。

System

System.arraycopy();
System.currentTimeMillis();
SystemClock.sleep();

自定义控件

textView.setY();
AppCompatTextView#setSupportBackgroundTintList(ColorStateList.valueOf(color));

SparseArray

  • put()
  • indexOfKey()
  • indexOfValue()
  • keyAt()
  • valueAt()

TypedValue

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, getResources().getDisplayMetrics());

setSoftInputMode

((Activity) mContext).getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

android.text.format.dateformat

http://blog.csdn.net/jason_wks/article/details/7412562

注册上下文菜单

registerForContextMenu(View view);
onContextItemSelected(MenuItem item);
onCreateContextMenu(ContextMenu menu, View v,  ContextMenuInfo menuInfo);

BaseColumns

BaseColumns接口有两个常量:1.总行数_count 2.每行的独特的_ID

实现BaseColumns接口以后,内部类就可以继承一个主键字段_ID,这也是很多android里的类所需要的,比如游标适配器(cursor adaptor)。这虽然不是必须,但是可以使数据库和android的框架协调工作。

LayoutInflater

inflate(int resource, ViewGroup root, boolean attachToRoot);  
  1. 如果root为null,attachToRoot将失去作用,设置任何值都没有意义。
  2. 如果root不为null,attachToRoot设为true,则会给加载的布局文件的指定一个父布局,即root。
  3. 如果root不为null,attachToRoot设为false,则会将布局文件最外层的所有layout属性进行设置,当该view被添加到父view当中时,这些layout属性会自动生效。
  4. 在不设置attachToRoot参数的情况下,如果root不为null,attachToRoot参数默认为true。

1、Android设置全屏的三种方式

1.1 代码设置

在setContentView()之前执行

requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题栏
int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setFlags(flag ,flag );//隐藏状态栏
setContentView(R.layout.main_activity);

当MainActivity继承的不是Activity,而是AppCompatActivity,而且主题不是NoActionBar的时候,调用requestWindowFeature(Window.FEATURE_NO_TITLE)无法隐藏标题栏,需要调用一下代码隐藏ActionBar

if (getSupportActionBar() != null){
       getSupportActionBar().hide();
}

1.2 调用Android自带的Theme

直接在AndroidManifest.xml中需要全屏显示的Activity属性中添加

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

1.3 自己定义全屏Theme

在style.xml文件中定义theme(如果没有style.xml,在res/values目录下创建)

<resources> 
    <style name="Theme.NoTitle_FullScreen"> 
        <item name="android:windowNoTitle">true</item>    
        <item name="android:windowFullscreen">true</item>      
    </style> 
</resources>

直接在AndroidManifest.xml中需要全屏显示的Activity属性中添加

android:theme="@style/Theme.NoTitle_FullScree"

横屏

@Override
protected void onResume() {
    if(getRequestedOrientation()!=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
    super.onResume();
}
android:screenOrientation="portrait"

分享

分享应用下载链接

//分享:https://play.google.com/store/apps/details?id=com.tencent.mobileqq
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT,"分享");
intent.putExtra(Intent.EXTRA_TEXT,"下载地址:" 
                + "https://play.google.com/store/apps/details?id=" + "packagename");
startActivity(Intent.createChooser(intent,"分享应用"));

位置分享

Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT,位置url);
startActivity(Intent.createChooser(intent,"位置分享"));

硬件加速

四个硬件加速级别

Application

<application android:hardwareAccelerated="true">
...
</application>

Activity

<activity android:hardwareAccelerated="true" />

Window

getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

View

view.setLayerType(View.LAYER_TYPE_SOFTWARE,null);

判定一个View是否能被硬加速

View.isHardwareAccelerated();//如果View附加到一个硬加速的window上就返回true
Canvas.isHardwareAccelerated();//如果Canvas被硬加速了就返回true.

使用系统的主题颜色

app:tabTextColor="?android:attr/textColorTertiaryInverse"

新闻客户端

记录已读状态

lvList.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                System.out.println("被点击:" + position);
                // 35311,34221,34234,34342
                // 在本地记录已读状态
                String ids = PrefUtils.getString(mActivity, "read_ids", "");
                String readId = mNewsList.get(position).id;
                if (!ids.contains(readId)) {
                    ids = ids + readId + ",";
                    PrefUtils.setString(mActivity, "read_ids", ids);
                }

                // mNewsAdapter.notifyDataSetChanged();
                changeReadState(view);// 实现局部界面刷新, 这个view就是被点击的item布局对象

                // 跳转新闻详情页
                Intent intent = new Intent();
                intent.setClass(mActivity, NewsDetailActivity.class);
                intent.putExtra("url", mNewsList.get(position).url);
                mActivity.startActivity(intent);
            }
        });

    /**
     * 改变已读新闻的颜色
     */
    private void changeReadState(View view) {
        TextView tvTitle = (TextView) view.findViewById(R.id.tv_title);
        tvTitle.setTextColor(Color.GRAY);
    }

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = View.inflate(mActivity, R.layout.list_news_item,
                        null);
                holder = new ViewHolder();
                holder.ivPic = (ImageView) convertView
                        .findViewById(R.id.iv_pic);
                holder.tvTitle = (TextView) convertView
                        .findViewById(R.id.tv_title);
                holder.tvDate = (TextView) convertView
                        .findViewById(R.id.tv_date);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            TabNewsData item = getItem(position);

            holder.tvTitle.setText(item.title);
            holder.tvDate.setText(item.pubdate);

            utils.display(holder.ivPic, item.listimage);

            String ids = PrefUtils.getString(mActivity, "read_ids", "");
            if (ids.contains(getItem(position).id)) {
                holder.tvTitle.setTextColor(Color.GRAY);
            } else {
                holder.tvTitle.setTextColor(Color.BLACK);
            }

            return convertView;
        }

ProgressBar

    <ProgressBar
        android:id="@+id/loading_progress"
        android:layout_width="@dimen/dp_22"
        android:layout_height="@dimen/dp_22"
        android:layout_marginRight="@dimen/dp_4"
        android:indeterminateDrawable="@drawable/sample_footer_loading_progress" />

sample_footer_loading_progress

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <rotate
            android:drawable="@drawable/sample_footer_loading"
            android:duration="500"
            android:fromDegrees="0.0"
            android:pivotX="50.0%"
            android:pivotY="50.0%"
            android:toDegrees="360.0" />
    </item>

</layer-list>

数据存储和数据传输单位

字节是由8个位所组成,可代表一个字符(A~Z)、数字(0~9)、或符号(,.?!%&+-*/),是内存储存数据的基本单位

  • 1 byte = 8 bit
  • 1 KB = 1024 bytes = 210 bytes
  • 1 MB = 1024 KB = 220 bytes
  • 1 GB = 1024 MB = 230 bytes

位:“位(bit)”是电子计算机中最小的数据单位。每一位的状态只能是0或1。

字节:8个二进制位构成1个“字节(Byte)”,它是存储空间的基本计量单位。1个字节可以储存1个英文字母或者半个汉字,换句话说,1个汉字占据2个字节的存储空间。

字:“字”由若干个字节构成,字的位数叫做字长,不同档次的机器有不同的字长。例如一台8位机,它的1个字就等于1个字节,字长为8位。如果是一台16位机,那么,它的1个字就由2个字节构成,字长为16位。字是计算机进行数据处理和运算的单位。

KB:在一般的计量单位中,通常K表示1000。例如:1公里= 1000米,经常被写为1km;1公斤=1000克,写为1kg。同样K在二进制中也有类似的含义。只是这时K表示1024,也就是2的10次 方。1KB表示1K个Byte,也就是1024个字节。

MB:计量单位中的M(兆)是10的6次方,见到M自然想起要在该数值的后边续上六个0,即扩大一百万倍。在二进制中,MB也表示到了百万级的数量级,但1MB不正好等于1000000字节,而是1048576字节,即 1MB = 2E+20 Bytes = 1048576Bytes。

计算机系统中的数据的计量单位。

在标准10进制公制度量系统中,倍率关系如下所示

  • kilo (k)* = 103 = 1,000 thousand 千
  • mega (M) = 106 = 1,000,000 million 百万
  • giga (G) = 10 9 = 1,000,000,000 billion 十亿
  • tera (T) = 10 12 = 1,000,000,000,000 trillion 万亿

在公制系统中, “k” 或者 “kilo” 前缀只使用小写字母

在计算机/通讯行业中,计算数据传送速度也使用每秒传送公制数据量来计算

  • 1 bit (b) = 0 or 1 = one binary digit 一个二进制位元
  • 1 kilobit(kb)=103 bits = 1,000 bits 一千位元
  • 1 Megabit(Mb)=106 bits = 1,000,000 bits 一百万位元
  • 1 Gigabit(Gb)=109 bits = 1,000,000,000 bits 一万亿位元

根据进制规定,传送速度可以有两种表示方法 bps 和 Bps,但是他们是有严格区别。Bps中的 B 使用的是二进制系统中的Byte字节 ,bps中的 b 是十进制系统中的位元。

在我们常说的56K拨号,100M局域网都是bps计量,当用于软件下载时,下载工具一般又以Bps计算,所以它们之间有 8 bit=1 Byte 的换算关系,那么56Kbps拨号极限下载速度是 56Kbps/8=7KBps 每秒下载7K字节 。

在数据存储,容量计算中,一般又结合公制的进制和二进制的数据计算方法来计算

(二进制)

  • 1 byte (B) = 8 bits (b) 字节=8个二进制位
  • 1 Kilobyte(K/KB)=210 bytes=1,024 bytes 千字节
  • 1 Megabyte(M/MB)=220 bytes=1,048,576 bytes 兆字节
  • 1 Gigabyte(G/GB)=230 bytes=1,073,741,824 bytes 千兆字节
  • 1 Terabyte(T/TB)=240 bytes=1,099,511,627,776 bytes吉字节

一些存储器厂家特别是硬盘厂家就更紧密结合十进制来计算,这就是为什么操作系统显示的容量与厂家标示的容量有些一些差异的原因

(十进制)

  • 1 byte (B) = 8 bits (b)
  • 1 Kilobyte (K / KB) = 103 bytes = 1,000 bytes
  • 1 Megabyte (M / MB) = 106 bytes = 1,000,000 bytes
  • 1 Gigabyte (G / GB) = 109 bytes = 1,000,000,000 bytes
  • 1 Terabyte (T / TB) = 1012 bytes = 1,000,000,000,000 bytes

翻译

So to talk, they need to decompose their objects into primitives that the operating system can understand, and marshall the objects across that boundary for you. The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.

尽管如此,进程需要将其对象分解成操作系统能够识别的原语,并将对象编组成跨越边界的对象。编写执行这一编组操作的代码是一项繁琐的工作,因此 Android 会使用 AIDL 来处理。

常用代码

public static String formatTime(long time) {
        String minute = String.valueOf(time / 60);
        String second = String.valueOf(time % 60);
        if (minute.length() == 1) {
            minute = "0" + minute;
        }
        if (second.length() == 1) {
            second = "0" + second;
        }
        return minute + "分" + second + "秒";
    }

DialogFragment

Activity的页面结构

  • PhoneWindow$DecorView
    • ActionBarOverlayLayout
      • FrameLayout:显示contentView
      • ActionBarcontainer:显示ActionBar

ActionBarOverlayLayout
ActionBarContainer
ActionBarContextView

ProgressBar

android:indeterminateDrawable

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
                android:oneshot="false">
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img1"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img2"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img3"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img4"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img5"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img6"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img7"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img8"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img9"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img10"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img11"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img12"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img13"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img14"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img15"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img16"
            android:gravity="left"/>
    </item>
    <item android:duration="80">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/img17"
            android:gravity="left"/>
    </item>
</animation-list>

Adapter

 public void addAll(List<T> elem) {
        this.data.addAll(elem);
        notifyDataSetChanged();
    }

    public void remove(T elem) {
        this.data.remove(elem);
        notifyDataSetChanged();
    }

    public void remove(int index) {
        this.data.remove(index);
        notifyDataSetChanged();
    }

    public void replaceAll(List<T> elem) {
        this.data.clear();
        this.data.addAll(elem);
        notifyDataSetChanged();
    }
public class CookFoodFragment extends BaseFragment {
    private boolean hasMore = true;
    public boolean isFirstLoad = true;
    private int mCurrentPage = 1;
    private int mPage = 1;
    ListView listView;
    private AddCustomCookAdapter mAdapter;
    private List<CustomCookItem> mFoodList = new ArrayList();
    PullToRefreshListView mPullRefreshListView;
    public int mTimeType = -1;
    public String record_on;

    public static CookFoodFragment newInstance(int time_type, String record_on) {
        CookFoodFragment fragment = new CookFoodFragment();
        fragment.mTimeType = time_type;
        fragment.record_on = record_on;  
        return fragment;
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.ft, container, false);
    }

    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.inject((Object) this, view);
        EventBus.getDefault().register(this);
    }

    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        this.listView = (ListView) this.mPullRefreshListView.getRefreshableView();
        this.listView.addHeaderView(LayoutInflater.from(getActivity()).inflate(R.layout.h4, null));
        this.mAdapter = new AddCustomCookAdapter(getActivity(), this.mFoodList);
        this.listView.setAdapter(this.mAdapter);
        this.mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
            public void onRefresh(PullToRefreshBase<ListView> pullToRefreshBase) {
                CookFoodFragment.this.mPage = 1;
                CookFoodFragment.this.mCurrentPage = CookFoodFragment.this.mPage;
                CookFoodFragment.this.hasMore = true;
                CookFoodFragment.this.loadData();
            }
        });
        this.mPullRefreshListView.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {
            public void onLastItemVisible() {
                if (CookFoodFragment.this.mPage > CookFoodFragment.this.mCurrentPage) {
                    CookFoodFragment.this.mCurrentPage = CookFoodFragment.this.mPage;
                    CookFoodFragment.this.loadData();
                }
            }
        });
        this.listView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (!CookFoodFragment.this.isRemoved()) {
                    if (position == 1) {
                        CustomCookListActivity.comeOnBaby(CookFoodFragment.this.getActivity());
                    }
                    CustomCookItem customCook = (CustomCookItem) parent.getAdapter().getItem(position);
                    if (customCook != null) {
                        RecordFood recordFood = new RecordFood();
                        recordFood.time_type = CookFoodFragment.this.mTimeType;
                        recordFood.record_on = CookFoodFragment.this.record_on;
                        recordFood.amount = 1.0f;
                        recordFood.calory = customCook.calory;
                        recordFood.food_name = customCook.name;
                        recordFood.unit_name = "份";
                        if (!TextUtils.isEmpty(customCook.photo)) {
                            if (customCook.photo.startsWith("http")) {
                                recordFood.thumb_img_url = customCook.photo;
                            } else {
                                recordFood.thumb_img_url = TimeLinePatterns.WEB_SCHEME + customCook.photo;
                            }
                        }
                        AddCustomDietFragment.newInstance(0, recordFood).show(CookFoodFragment.this.getFragmentManager(), "addCustomDietFragment");
                    }
                }
            }
        });
    }

    public void firstLoad() {
        new Handler().postDelayed(new Runnable() {
            public void run() {
                if (CookFoodFragment.this.isAdded()) {
                    CookFoodFragment.this.mPullRefreshListView.setRefreshing();
                    CookFoodFragment.this.isFirstLoad = false;
                }
            }
        }, 500);
    }

    private void loadData() {
        if (this.hasMore) {
            FoodApi.getCustomMenus(getActivity(), this.mPage, new JsonCallback(getActivity()) {
                public void ok(JSONObject object) {
                    super.ok(object);
                    CookFoodFragment.this.refreshData(object);
                }

                public void onFinish() {
                    super.onFinish();
                    CookFoodFragment.this.mPullRefreshListView.onRefreshComplete();
                }
            });
        }
    }

    private void refreshData(JSONObject object) {
        if (this.mPage == 1) {
            this.mFoodList.clear();
        }
        List<CustomCookItem> foodList = FastJsonUtils.parseList(object.optString("menus"), CustomCookItem.class);
        if (foodList == null || foodList.size() <= 0) {
            this.hasMore = false;
        } else {
            this.mFoodList.addAll(foodList);
            this.mPage++;
        }
        this.mAdapter.notifyDataSetChanged();
    }

    public void onEventMainThread(MyFoodEvent myFoodEvent) {
        if (myFoodEvent != null) {
            switch (myFoodEvent.getFlag()) {
                case 3:
                    this.mPage = 1;
                    loadData();
                    return;
                default:
                    return;
            }
        }
    }

    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.reset(this);
        EventBus.getDefault().unregister(this);
    }
}

虚线

<View
    android:id="@id/divider_weight"
    android:layout_width="80.0dip"
    android:layout_height="3.0px"
    android:layout_below="@id/tv_weight"
    android:layout_centerHorizontal="true"
    android:background="@drawable/bg"
    android:layerType="software"/>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="line">
    <stroke
        android:width="2.0px"
        android:color="#44ffffff"
        android:dashGap="1.0dip"
        android:dashWidth="2.0dip"/>
</shape>

background

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="4.0dip" />
    <stroke android:width="1.0px" android:color="#ffdfdfdf" />
    <solid android:color="#ffffffff" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <corners android:radius="4.0dip"/>
    <stroke
        android:width="1.0px"
        android:color="#ff62cc74"/>
    <solid android:color="#ffffffff"/>
</shape>

Space

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值