自定義梯形view與XRecyclerView的結合
一。http(工具類)
1.
HttpConfig
public class HttpConfig { public static String goods_url="http://ttpc.dftoutiao.com/jsonpc/refresh"; public static final int TYPE1 = 3;//條目是三張圖 public static final int TYPE2 = 1;//條目是1張圖 }
2.OkLoadListener
public interface OkLoadListener { void okLoadSuccess(String json); void okLoadError(String error);}
3.AppUtil(自定義view)
public class AppUtil { /** * * @param context * @return 螢幕寬度 */ public static int screenWidth(Context context){ DisplayMetrics metrics = context.getResources().getDisplayMetrics(); return metrics.widthPixels; } }
4.NetWorkUtil(網路連線)
public class NetWorkUtil { /** * * @return 是否有活動的網路連線 */ public final static boolean hasNetWorkConnection(Context context){ //獲取連線活動管理器 final ConnectivityManager connectivityManager= (ConnectivityManager) context. getSystemService(Context.CONNECTIVITY_SERVICE); //獲取連結網路資訊 final NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo(); return (networkInfo!= null && networkInfo.isAvailable()); } /** * @return 返回boolean ,是否為wifi網路 * */ public final static boolean hasWifiConnection(Context context) { final ConnectivityManager connectivityManager= (ConnectivityManager) context. getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo networkInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); //是否有網路並且已經連線 return (networkInfo!=null&& networkInfo.isConnectedOrConnecting()); } /** * @return 返回boolean,判斷網路是否可用,是否為行動網路 * */ public final static boolean hasGPRSConnection(Context context){ //獲取活動連線管理器 final ConnectivityManager connectivityManager= (ConnectivityManager) context. getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo networkInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); return (networkInfo!=null && networkInfo.isAvailable()); } /** * @return 判斷網路是否可用,並返回網路型別,ConnectivityManager.TYPE_WIFI,ConnectivityManager.TYPE_MOBILE,不可用返回-1 */ public static final int getNetWorkConnectionType(Context context){ final ConnectivityManager connectivityManager=(ConnectivityManager) context. getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo wifiNetworkInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); final NetworkInfo mobileNetworkInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); if(wifiNetworkInfo!=null &&wifiNetworkInfo.isAvailable()) { return ConnectivityManager.TYPE_WIFI; } else if(mobileNetworkInfo!=null &&mobileNetworkInfo.isAvailable()) { return ConnectivityManager.TYPE_MOBILE; } else { return -1; } } }
5.HttpUtils(請求工具)
public class HttpUtils { private static final String TAG = "HttpUtils-----"; private static HttpUtils httpUtils; private final int SUCCESS = 0; private final int ERROR = 1; private MyHandler myHandler = new MyHandler(); private OkLoadListener okLoadListener; public static HttpUtils getHttpUtils() { if (httpUtils == null) { httpUtils = new HttpUtils(); } return httpUtils; } class MyHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case SUCCESS: //成功 String json = (String) msg.obj; okLoadListener.okLoadSuccess(json); break; case ERROR: //失敗 String error = (String) msg.obj; okLoadListener.okLoadError(error); break; } } } //get public void okGet(String url) { OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new MyIntercepter()).build(); Request request = new Request.Builder().url(url).build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Message message = myHandler.obtainMessage(); message.what = ERROR; message.obj = e.getMessage(); myHandler.sendMessage(message); } @Override public void onResponse(Call call, Response response) throws IOException { Message message = myHandler.obtainMessage(); message.what = SUCCESS; message.obj = response.body().string(); myHandler.sendMessage(message); } }); } public void setOkLoadListener(OkLoadListener okLoadListener) { this.okLoadListener = okLoadListener; } //post public void okPost(String url, Map<String, String> params) { OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new MyIntercepter()).build(); FormBody.Builder builder = new FormBody.Builder(); Set<String> keySet = params.keySet(); for (String key : keySet) { String value = params.get(key); builder.add(key, value); } FormBody formBody = builder.build(); Request request = new Request.Builder().url(url).post(formBody).build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Message message = myHandler.obtainMessage(); message.what = ERROR; message.obj = e.getMessage(); myHandler.sendMessage(message); } @Override public void onResponse(Call call, Response response) throws IOException { Message message = myHandler.obtainMessage(); message.what = SUCCESS; message.obj = response.body().string(); myHandler.sendMessage(message); } }); } //攔截器 class MyIntercepter implements Interceptor { //intercept 攔截 @Override public Response intercept(Chain chain) throws IOException { //新增公共引數 // post 取出原來所有的引數,將之加到新的請求體裡面。然後讓請求去執行 Request request = chain.request(); //獲取請求方法 String method = request.method(); if (method.equals("GET")) {//---------------------------GET 攔截 //取出url地址 String url = request.url().toString(); //拼接公共引數 boolean contains = url.contains("?"); if (contains) { url = url + "&source=android"; } else { url = url + "?source=android"; } Request request1 = request.newBuilder().url(url).build(); Response response = chain.proceed(request1); return response; } else if (method.equals("POST")) {//---------------------POST 攔截 RequestBody body = request.body();//請求體 if (body instanceof FormBody) { //建立新的請求體 FormBody.Builder newBuilder = new FormBody.Builder(); for (int i = 0; i < ((FormBody) body).size(); i++) { String key = ((FormBody) body).name(i); String value = ((FormBody) body).value(i); newBuilder.add(key, value); } //新增公共引數 newBuilder.add("source", "android"); FormBody newBody = newBuilder.build(); //建立新的請求體 Request request1 = request.newBuilder().post(newBody).build(); //去請求 Response response = chain.proceed(request1); return response; } } return null; } } //上傳檔案(圖片) public void upLoadImage(String url, String path) {//url 要上傳的地址。path 要上傳的檔案路徑 //媒體型別 MediaType mediaType = MediaType.parse("image/*"); //multipartbody MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM); File file = new File(path); MultipartBody multipartBody = builder.addFormDataPart("file", file.getName(), RequestBody.create(mediaType, file)).build(); OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder().url(url).post(multipartBody).build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.d(TAG, "上傳失敗0----: "); } @Override public void onResponse(Call call, Response response) throws IOException { Log.d(TAG, "上傳成功: "); } }); } }二.dbsqlite(資料庫)
1.DbHelper
public class DbHelper extends SQLiteOpenHelper{ //資料庫檔名稱 private static final String DB_NAME = "news.db"; public static final String NEWS_TABLE_NAME = "news"; private static final int VERSION = 1; public DbHelper(Context context) { super(context, DB_NAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { String sql = "create table " + NEWS_TABLE_NAME + " (_id Integer PRIMARY KEY ,json text)"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
三.model
1. GoodsListener
public interface GoodsListener { void getSuccess(String json); void getError(String error); }
2.IModel
public interface IModel { public void getGoodsListData(String url, Map<String,String> map,GoodsListener goodsListener); }
3.ModelImpl
public class ModelImpl implements IModel{ @Override public void getGoodsListData(String url, Map<String, String> map, final GoodsListener goodsListener) { HttpUtils httpUtils = HttpUtils.getHttpUtils(); httpUtils.okPost(url,map); httpUtils.setOkLoadListener(new OkLoadListener() { @Override public void okLoadSuccess(String json) { goodsListener.getSuccess(json); } @Override public void okLoadError(String error) { goodsListener.getError(error); } }); } }
四.presenter
1.IPresenter
public interface IPresenter { void showGoodsListToView(IModel iModel, IMainView iMainView); }
2.PresenterImpl
public class PresenterImpl implements IPresenter{ private static final String TAG = "PresenterImpl-----"; @Override public void showGoodsListToView(IModel iModel, final IMainView iMainView) { Map<String,String> map = new HashMap<>(); map.put("type",iMainView.getContent()+""); iModel.getGoodsListData(HttpConfig.goods_url, map, new GoodsListener() { @Override public void getSuccess(String json) { if(!TextUtils.isEmpty(json)){ String s = json.replace("null(", "").replace(")", ""); Log.d(TAG, "資料----: "+s); UserBean userBean = new Gson().fromJson(s,UserBean.class); iMainView.showGoodsList(userBean); } } @Override public void getError(String error) { Log.d(TAG, "getError: "+error); } }); } }
五.bean
1.UserBean(演示bean包)
public class UserBean { public String stat; public List<Data> data; public String getStat() { return stat; } public void setStat(String stat) { this.stat = stat; } public List<Data> getData() { return data; } public void setData(List<Data> data) { this.data = data; } public class Data { public String topic; public String source; public List<IMG> miniimg; public String getTopic() { return topic; } public void setTopic(String topic) { this.topic = topic; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } public List<IMG> getMiniimg() { return miniimg; } public void setMiniimg(List<IMG> miniimg) { this.miniimg = miniimg; } public class IMG { public String src; public String getSrc() { return src; } public void setSrc(String src) { this.src = src; } } } }
六.view
1.ThreeColorView (自定義view)
public class ThreeColorView extends ViewGroup{ public ThreeColorView(Context context) { super(context); } public ThreeColorView(Context context, AttributeSet attrs) { super(context, attrs); } public ThreeColorView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //此控制元件的高度 int totalHeight = 0; //此控制元件的寬度 int totalWidth = 0; //得到子view數量 int child = getChildCount(); if(child > 0){ for (int i = 0; i < child; i++) {//遍歷子控制元件 //得到此容器所有的子view View view = getChildAt(i); totalHeight += view.getMeasuredHeight(); measureChild(view,widthMeasureSpec,heightMeasureSpec); } } totalWidth = AppUtil.screenWidth(getContext()); System.out.println("width:"+totalWidth); System.out.println("height:"+totalHeight); //設定寬度和高度給當前view,通過下面這個方法 setMeasuredDimension(totalWidth,totalHeight); } /** * 把此view的最終的寬度和高度定下來 * * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int l = 0; int t = 0; int r = 0; int b = 0; int childCount = getChildCount(); for (int i = 0; i <childCount ; i++) { //得到每一個view的物件 final View view = getChildAt(i); view.layout(l,t,l+view.getMeasuredWidth(),t + view.getMeasuredHeight()); l += view.getMeasuredWidth(); System.out.println("llll:"+l); t += view.getMeasuredHeight(); if(l+view.getMeasuredWidth()>AppUtil.screenWidth(getContext())){ l = 0; } //點選事件 final int finalI = i; view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getContext(), finalI +":點選位置", Toast.LENGTH_SHORT).show(); TextView textView = (TextView) view; Toast.makeText(getContext(), textView.getText().toString() +"文字", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(getContext(), MainActivity.class); intent.putExtra("id",textView.getText().toString()); getContext().startActivity(intent); } }); view.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { Toast.makeText(getContext(), finalI +":長按位置", Toast.LENGTH_SHORT).show(); removeView(view); return true; } }); } } }
2.ThreeColorActivity(自定義view頁面)
public class ThreeColorActivity extends AppCompatActivity { private ThreeColorView threeColorView; private int count = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_three_color); threeColorView = (ThreeColorView) findViewById(R.id.threecolorview); } public void add(View view){ count++; int width = AppUtil.screenWidth(this); TextView textView = new TextView(this); textView.setText(count+""); textView.setGravity(Gravity.CENTER); textView.setTextColor(getResources().getColor(R.color.white)); ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView, "translationX", (width - width / 3), 0); objectAnimator.setDuration(3000); objectAnimator.start(); if(count == 1 || count == 4 || count == 7){ textView.setBackgroundColor(getResources().getColor(R.color.colorAccent)); }else { textView.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark)); } threeColorView.addView(textView); //得到view的屬性引數 ViewGroup.LayoutParams params = textView.getLayoutParams(); params.width = width/3; params.height = 70; textView.setLayoutParams(params); } }
2.5自定義view對應的佈局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/add" android:onClick="add" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <com.example.lenovo.yuekaomoni_0530.view.widget.ThreeColorView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/threecolorview"> </com.example.lenovo.yuekaomoni_0530.view.widget.ThreeColorView> </LinearLayout>
3. IMainView
public interface IMainView { void showGoodsList(UserBean list); int getContent(); }
4.MainActivity (主方法)
public class MainActivity extends AppCompatActivity implements IMainView{ private int page = 5010; private XRecyclerView rv; private PresenterImpl presenter; private boolean isRefresh = true;//判斷是下啦重新整理還是上啦載入 private DbHelper dbHelper; private MyAdapter myAdapter; private List<UserBean.Data> data; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } private void initData() { if (getIntent().getExtras() != null) { page = 5010 + Integer.parseInt(getIntent().getExtras().getString("id")); } if (NetWorkUtil.hasWifiConnection(this) || NetWorkUtil.hasGPRSConnection(this)) { presenter = new PresenterImpl(); presenter.showGoodsListToView(new ModelImpl(), this); }else { Toast.makeText(this, "網路不通暢,請稍後再試!", Toast.LENGTH_SHORT).show(); String json = null; // //獲取資料庫物件,可讀 SQLiteDatabase db = dbHelper.getReadableDatabase(); //獲取資料庫的遊標 Cursor cursor = db.rawQuery("select * from news", null); while (cursor.moveToNext()){ json = cursor.getString(cursor.getColumnIndex("json")); } //本地列表重新整理 fillLocalData(json); } } /** * 本地列表重新整理 * @param json */ private void fillLocalData(String json) { UserBean news = new Gson().fromJson(json,UserBean.class); myAdapter = new MyAdapter(data, this,news); rv.setAdapter(myAdapter); } private void initView() { rv = (XRecyclerView)findViewById(R.id.xre); //設定區域性重新整理動畫 rv.setItemAnimator(new DefaultItemAnimator()); //上拉載入 rv.setLoadingMoreEnabled(true); //下拉重新整理 rv.setPullRefreshEnabled(true); rv.setLayoutManager(new LinearLayoutManager(this)); rv.setLoadingListener(new XRecyclerView.LoadingListener() { @Override public void onRefresh() { isRefresh = true; //下拉重新整理 page = 5010; initData(); } @Override public void onLoadMore() { isRefresh = false; page++; initData(); } }); } @Override public void showGoodsList(UserBean list) { String json = new Gson().toJson(list); System.out.println("size:" + list.getData().size()); data =list.data; if(isRefresh) { MyAdapter myAdapter = new MyAdapter(data, this,list); rv.setAdapter(myAdapter); rv.refreshComplete(); //儲存json串資料 // SQLiteDatabase db = dbHelper.getWritableDatabase(); // ContentValues contentValues = new ContentValues(); // contentValues.put("json", json); // db.insert(DbHelper.NEWS_TABLE_NAME, null, contentValues); }else{ if(myAdapter != null){ myAdapter.loadMore(data); } rv.loadMoreComplete(); } } public int getContent() { int s =page; return s; } }
4.5主方法對應的佈局
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.jcodecraeer.xrecyclerview.XRecyclerView android:id="@+id/xre" android:layout_width="match_parent" android:layout_height="wrap_content"> </com.jcodecraeer.xrecyclerview.XRecyclerView></android.support.constraint.ConstraintLayout>
5.MyAdapter (介面卡)
public class MyAdapter extends XRecyclerView.Adapter<XRecyclerView.ViewHolder>{ private List<UserBean.Data> list; private Context context; private UserBean userBean; public MyAdapter(List<UserBean.Data> list, Context context,UserBean userBean) { this.list = list; this.context = context; this.userBean = userBean; } public void loadMore(List<UserBean.Data> data) { if (list != null) { list.addAll(data); notifyDataSetChanged(); } } @Override public XRecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if(viewType == HttpConfig.TYPE1){ View view = LayoutInflater.from(context).inflate(R.layout.news_item_layout, parent, false); return new Type1ViewHolder(view); }else { View view = LayoutInflater.from(context).inflate(R.layout.news_item2_layout, parent, false); return new Type2ViewHolder(view); } } @Override public void onBindViewHolder(final XRecyclerView.ViewHolder holder, int position) { //長按刪除 holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("刪除"); builder.setNegativeButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //得到下標 int pos = holder.getLayoutPosition(); System.out.println("pos----"+pos); list.remove(pos); userBean.data = list; String json = new Gson().toJson(userBean); notifyDataSetChanged(); //notifyItemRemoved(pos);//區域性刪除當前view並區域性重新整理 } }); builder.setNeutralButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); builder.show(); return true; } }); //多條目載入 UserBean.Data dataBean = list.get(position); if(holder instanceof Type1ViewHolder){ ((Type1ViewHolder) holder).title.setText(dataBean.getTopic()); Glide.with(context).load(dataBean.getMiniimg().get(0).getSrc()).into(((Type1ViewHolder) holder).iv1); }else if(holder instanceof Type2ViewHolder){ ((Type2ViewHolder) holder).title.setText(dataBean.getTopic()); if(dataBean.getMiniimg()!=null&&dataBean.getMiniimg().size()>0){ if(dataBean.getMiniimg().size() == 1){ Glide.with(context).load(dataBean.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iv1); Glide.with(context).load(dataBean.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iv2); Glide.with(context).load(dataBean.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iv3); }else if (dataBean.getMiniimg().size() == 2){ Glide.with(context).load(dataBean.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iv1); Glide.with(context).load(dataBean.getMiniimg().get(1).getSrc()).into(((Type2ViewHolder) holder).iv2); Glide.with(context).load(dataBean.getMiniimg().get(1).getSrc()).into(((Type2ViewHolder) holder).iv3); }else{ Glide.with(context).load(dataBean.getMiniimg().get(0).getSrc()).into(((Type2ViewHolder) holder).iv1); Glide.with(context).load(dataBean.getMiniimg().get(1).getSrc()).into(((Type2ViewHolder) holder).iv2); Glide.with(context).load(dataBean.getMiniimg().get(2).getSrc()).into(((Type2ViewHolder) holder).iv3); } } } } @Override public int getItemViewType(int position) { return position % 3 ==0? HttpConfig.TYPE1:HttpConfig.TYPE2; } @Override public int getItemCount() { return list.size(); } class Type1ViewHolder extends XRecyclerView.ViewHolder{ private TextView title; private ImageView iv1; public Type1ViewHolder(View itemView) { super(itemView); iv1 = (ImageView) itemView.findViewById(R.id.pic1); title = (TextView) itemView.findViewById(R.id.title1); } } class Type2ViewHolder extends XRecyclerView.ViewHolder{ private TextView title; private ImageView iv1,iv2,iv3; public Type2ViewHolder(View itemView) { super(itemView); iv1 = (ImageView) itemView.findViewById(R.id.pic_1); iv2 = (ImageView) itemView.findViewById(R.id.pic_2); iv3 = (ImageView) itemView.findViewById(R.id.pic_3); title = (TextView) itemView.findViewById(R.id.title_1); } } }
5.5_1 news_item_layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/pic1" android:src="@mipmap/ic_launcher" android:layout_width="wrap_content" android:scaleType="centerCrop" android:layout_height="wrap_content"/> <LinearLayout android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginTop="10dp"> <TextView android:id="@+id/title1" android:layout_marginLeft="10dp" android:text="我是標題" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>
5.5_2 news_item2_layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:text="標題" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/title_1"/> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:scaleType="centerCrop" android:padding="10dp" android:src="@mipmap/ic_launcher" android:id="@+id/pic_1" android:layout_weight="1" android:layout_width="0dp" android:layout_height="50dp" /> <ImageView android:scaleType="centerCrop" android:padding="10dp" android:src="@mipmap/ic_launcher" android:id="@+id/pic_2" android:layout_weight="1" android:layout_width="0dp" android:layout_height="50dp" /> <ImageView android:scaleType="centerCrop" android:padding="10dp" android:src="@mipmap/ic_launcher" android:id="@+id/pic_3" android:layout_weight="1" android:layout_width="0dp" android:layout_height="50dp" /> </LinearLayout> </LinearLayout>
七.許可權
1.許可權
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.INTERNET" /><application android:allowBackup="true" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".view.widget.ThreeColorActivity" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".view.MainActivity"></activity></application>
2.
compile 'com.google.code.gson:gson:2.6.2'compile 'com.squareup.okhttp3:okhttp:3.3.0'compile 'com.github.bumptech.glide:glide:3.7.0'compile 'com.jcodecraeer:xrecyclerview:1.5.9'
configurations.all { resolutionStrategy.eachDependency { DependencyResolveDetails details -> def requested = details.requested if (requested.group == 'com.android.support') { if (!requested.name.startsWith("multidex")) { details.useVersion '25.2.0' } } } }
3.values下的colors
<color name="white">#FFffff</color>
相關文章
- 自定義View合輯(3)-下雨View
- 自定義View合輯(4)-太極View
- 自定義View合輯(1)-時鐘View
- 自定義VIEWView
- 自定義View合輯(2)-餅狀圖View
- Android自定義View:View(二)AndroidView
- 【朝花夕拾】Android自定義View篇之(十一)View的滑動,彈性滑動與自定義PagerViewAndroidView
- 自定義View以及事件分發總結View事件
- flutter自定義View(CustomPainter) 之 canvas的方法總結FlutterViewAICanvas
- Android自定義View整合AndroidView
- 自定義View之SwitchViewView
- Android自定義view-自繪ViewAndroidView
- Flutter自定義View的實現FlutterView
- android自定義view(自定義數字鍵盤)AndroidView
- 自定義View合輯(6)-波浪(貝塞爾曲線)View
- 【朝花夕拾】Android自定義View篇之(四)自定義View的三種實現方式及自定義屬性詳解AndroidView
- 自定義view————Banner輪播View
- Flutter 自定義繪製 ViewFlutterView
- Flutter自定義View(二)—— MultiChildRenderObejctWidgetFlutterView
- 重拾Android自定義ViewAndroidView
- Android自定義View:ViewGroup(三)AndroidView
- Android 自定義 View 之 LeavesLoadingAndroidView
- Android自定義View之Canvas的使用AndroidViewCanvas
- 自定義View合輯(8)-跳躍的小球(貝塞爾曲線)View
- Android自定義View之事件分發機制總結AndroidView事件
- Android 自定義View:深入理解自定義屬性(七)AndroidView
- 自定義View的硬體加速問題View
- Android自定義View之分貝儀AndroidView
- 自定義View實用小技巧View
- 自定義View 之 RecyclerView.ItemDecorationView
- Android自定義View之捲尺AndroidView
- 利用Xfermode 自定義形狀ViewView
- 自定義View-波浪動效View
- 自定義View-扭曲動效View
- Android自定義View注意事項AndroidView
- Android自定義View-卷軸AndroidView
- Android自定義View 水波氣泡AndroidView
- Android 自定義View 點贊效果AndroidView