精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

鴻蒙小游戲-數字華容道自定義組件的踩坑記錄

開發
前兩天看到HarmonyOS開發者官網上發布的一個挑戰HarmonyOS分布式趣味應用的帖子,然后有個想法想搞一個小游戲出來,結果三天的時間都卡在了自定義組件上。

[[430553]]

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

前兩天看到HarmonyOS開發者官網上發布的一個挑戰HarmonyOS分布式趣味應用的帖子,然后有個想法想搞一個小游戲出來,結果三天的時間都卡在了自定義組件上,使用了各種方式方法去實現功能,但是還是沒有達到預期的效果,暫時先做個小總結,其實坑有的時候真的很深…

一、效果演示

小應用其實也挺簡單,以前也見到過,叫做數字華容道,當你把所在的數字以順序放置完成后游戲結束。

其實屬于益智類的小游戲了;

最終實現效果:

鴻蒙小游戲-數字華容道  自定義組件的踩坑記錄-鴻蒙HarmonyOS技術社區

當前實現效果:

鴻蒙小游戲-數字華容道  自定義組件的踩坑記錄-鴻蒙HarmonyOS技術社區

二、實現過程

暫時說一下現在的進度,每一個方塊可以表示一個棋子,棋子的名稱也就是3*3的九宮格,1-9的數字,只是最后一個數字單獨設置為空白。點擊空白周圍的棋子可以與這個空白棋子做一次位置調換,直到將所有棋子順序排列完成為止。

這里先說一個這個棋子,棋子有兩個東西需要被記住,一個是棋子的坐標就是在九宮格里面的位置,另一個就是棋子的名稱;所以選擇使用自定義組件的方式將坐標和名稱進行一個綁定。

Position.java

  1. /** 
  2.  * 定義棋子的位置 
  3.  */ 
  4. public class Position { 
  5.     public int sizeX; // 總列數 
  6.     public int sizeY; // 總行數 
  7.     public int x; // 橫坐標 
  8.     public int y; // 縱坐標 
  9.  
  10.     public Position() { 
  11.     } 
  12.  
  13.     public Position(int sizeX, int sizeY) { 
  14.         this.sizeX = sizeX; 
  15.         this.sizeY = sizeY; 
  16.     } 
  17.  
  18.     public Position(int sizeX, int sizeY, int x, int y) { 
  19.         this.sizeX = sizeX; 
  20.         this.sizeY = sizeY; 
  21.         this.x = x; 
  22.         this.y = y; 
  23.     } 
  24.  
  25.     public Position(Position orig) { 
  26.         this(orig.sizeX, orig.sizeY, orig.x, orig.y); 
  27.     } 
  28.  
  29.     /** 
  30.      * 移動到下一個位置 
  31.      */ 
  32.     public boolean moveToNextPosition() { 
  33.         if (x < sizeX - 1) { 
  34.             x++; 
  35.         } else if (y < sizeY - 1) { 
  36.             x = 0; 
  37.             y++; 
  38.         } else { 
  39.             return false
  40.         } 
  41.         return true
  42.     } 
  43.  
  44.     @Override 
  45.     public String toString() { 
  46.         return "Position{" + 
  47.                 "x=" + x + 
  48.                 ", y=" + y + 
  49.                 '}'
  50.     } 

CubeView.java

  1. public class CubeView extends ComponentContainer { 
  2.  
  3.     private Position mPosition; 
  4.     private int mNumber; 
  5.  
  6.     private Text mTextCub; 
  7.     private int mTextSize = 20; 
  8.  
  9.     public CubeView(Context context) { 
  10.         super(context); 
  11.         init(); 
  12.     } 
  13.  
  14.     public CubeView(Context context, AttrSet attrSet) { 
  15.         super(context, attrSet); 
  16.         init(); 
  17.     } 
  18.  
  19.     private void init(){ 
  20.         Component component = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_cube_view_item, this, false); 
  21.         mTextCub = (Text) component.findComponentById(ResourceTable.Id_tv_item); 
  22.         mTextCub.setTextSize(mTextSize, Text.TextSizeType.VP); 
  23.     } 
  24.  
  25.     public void setNumber(int n) { 
  26.         mNumber = n; 
  27.         mTextCub.setText(String.valueOf(n)); 
  28.     } 
  29.  
  30.  
  31.     public int getNumber() { 
  32.         return mNumber; 
  33.     } 
  34.  
  35.     public Position getPosition() { 
  36.         return mPosition; 
  37.     } 
  38.  
  39.     public void setPosition(Position position) { 
  40.         this.mPosition = position; 
  41.     } 
  42.  
  43.     @Override 
  44.     public String toString() { 
  45.         return "CubeView{" + 
  46.                 "mPosition=" + mPosition + 
  47.                 ", mNumber=" + mNumber + 
  48.                 '}'
  49.     } 

 cube_view_item.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="match_content" 
  5.     ohos:width="match_content"
  6.     <Text 
  7.         ohos:id="$+id:tv_item" 
  8.         ohos:height="100vp" 
  9.         ohos:width="100vp" 
  10.         ohos:background_element="$graphic:cube_view_bg" 
  11.         ohos:text="1" 
  12.         ohos:text_alignment="center" 
  13.         ohos:text_color="$color:cubeViewStroke" 
  14.         ohos:text_size="20vp"
  15.         ></Text> 
  16. </DirectionalLayout> 

到這問題就來了,因為在代碼中只是使用到了setText()方法,那么有人會問我為什么不直接繼承Text組件,多寫一個布局有點麻煩了不是?

第一個坑

這里就是第一個坑了,因為在以前寫Android自定義控件的時候,對于簡單的組件來說直接繼承它的組件名稱就可以了,不用去繼承公共類然后再去使用布局去定位到里面的組件。原本我也是這么寫的,CubeView直接繼承Text沒有毛病可以使用,可以看到兩者間并無差別。

  1. public class CubeView extends Text { 
  2.  
  3.     private Position mPosition; 
  4.     private int mNumber; 
  5.  
  6.  
  7.     public CubeView(Context context) { 
  8.         super(context); 
  9.         init(); 
  10.     } 
  11.  
  12.     public CubeView(Context context, AttrSet attrSet) { 
  13.         super(context, attrSet); 
  14.         init(); 
  15.     } 
  16.  
  17.     private void init(){ 
  18.          
  19.     } 
  20.  
  21.     public void setNumber(int n) { 
  22.         mNumber = n; 
  23.         setText(String.valueOf(n)); 
  24.     } 
  25.  
  26.  
  27.     public int getNumber() { 
  28.         return mNumber; 
  29.     } 
  30.  
  31.     public Position getPosition() { 
  32.         return mPosition; 
  33.     } 
  34.  
  35.     public void setPosition(Position position) { 
  36.         this.mPosition = position; 
  37.     } 
  38.  
  39.     @Override 
  40.     public String toString() { 
  41.         return "CubeView{" + 
  42.                 "mPosition=" + mPosition + 
  43.                 ", mNumber=" + mNumber + 
  44.                 '}'
  45.     } 

但是在調用組件的時候出現了問題,因為我需要把這個棋子的組件添加到我的棋盤布局中,那么就需要先引入這個組件。引入組件后出問題了,布局報錯(在原來Android引入自定義組件的時候,單個組件也是可以直接引入的);報錯原因是,我最外層沒有放置布局導致不能直接識別單個組件,但是如果我加上一個布局的話,文件不會報錯,但是在我的棋盤上不能拿到這個棋子的組件;

鴻蒙小游戲-數字華容道  自定義組件的踩坑記錄-鴻蒙HarmonyOS技術社區

為此我只能將棋子的自定義組件寫成了布局引入方式。

到這里,棋子的開發工作也就基本做完了,下面要對棋盤進行布局。還是選擇自定義組件的方式;

cube_view.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <com.example.codelabs_games_hrd.CubeView 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:background_element="$graphic:cube_view_bg" 
  5.     ohos:height="100vp" 
  6.     ohos:width="100vp" 
  7.     ohos:id="$+id:title_bar_left" 
  8.     ohos:text="1" 
  9.     ohos:text_alignment="center" 
  10.     ohos:text_color="$color:cubeViewStroke" 
  11.     ohos:text_size="20vp" 
  12.  
  13.     > 
  14. </com.example.codelabs_games_hrd.CubeView> 

 ability_game.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <StackLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="match_parent" 
  5.     ohos:width="match_parent" 
  6.     ohos:background_element="$color:cubeViewBg"
  7.  
  8.     <com.example.codelabs_games_hrd.BoardView 
  9.         ohos:id="$+id:board" 
  10.         ohos:height="300vp" 
  11.         ohos:width="300vp" 
  12.         ohos:layout_alignment="center" 
  13.         ohos:background_element="$color:boardViewBg"
  14.     </com.example.codelabs_games_hrd.BoardView> 
  15.  
  16.     <Text 
  17.         ohos:id="$+id:tvCheat" 
  18.         ohos:height="10vp" 
  19.         ohos:width="10vp"></Text> 
  20.  
  21.     <Text 
  22.         ohos:id="$+id:mask" 
  23.         ohos:height="match_parent" 
  24.         ohos:width="match_parent" 
  25.         ohos:background_element="$color:cubeViewBg" 
  26.         ohos:text="123456789" 
  27.         ohos:text_size="48vp"></Text> 
  28.  
  29. </StackLayout> 

BoardView.java

  1. public class BoardView extends ComponentContainer implements ComponentContainer.EstimateSizeListener, ComponentContainer.ArrangeListener { 
  2.     private static final String TAG = "BoardView"
  3.     /** 
  4.      * 每一行有多少個棋子 
  5.      */ 
  6.     private int mSizeX = 3; 
  7.     /** 
  8.      * 有多少行棋子 
  9.      */ 
  10.     private int mSizeY = 3; 
  11.  
  12.  
  13.     private int maxWidth = 0; 
  14.  
  15.     private int maxHeight = 0; 
  16.  
  17.     private int mChildSize; 
  18.  
  19.     private Position mBlankPos; 
  20.     private CubeView[] mChildren; 
  21.  
  22.     private OnFinishListener mFinishListener; 
  23.  
  24.     private int xx = 0; 
  25.  
  26.     private int yy = 0; 
  27.  
  28.     private int lastHeight = 0; 
  29.  
  30.     // 子組件索引與其布局數據的集合 
  31.     private final Map<Integer, Layout> axis = new HashMap<>(); 
  32.  
  33.     //位置及大小 
  34.     private static class Layout { 
  35.         int positionX = 0; 
  36.         int positionY = 0; 
  37.         int width = 0; 
  38.         int height = 0; 
  39.     } 
  40.  
  41.  
  42.     private void invalidateValues() { 
  43.         xx = 0; 
  44.         yy = 0; 
  45.         maxWidth = 0; 
  46.         maxHeight = 0; 
  47.         axis.clear(); 
  48.     } 
  49.  
  50.     public BoardView(Context context) { 
  51.         super(context); 
  52.     } 
  53.  
  54.     public BoardView(Context context, AttrSet attrs) { 
  55.         super(context, attrs); 
  56.         setEstimateSizeListener(this); 
  57.         setArrangeListener(this); 
  58.         init(); 
  59.     } 
  60.  
  61.     private void init() { 
  62.         mChildSize = mSizeX * mSizeY - 1; 
  63.         mChildren = new CubeView[mChildSize]; 
  64.         Position p = new Position(mSizeX, mSizeY); 
  65.         for (int i = 0; i < mChildSize; i++) { 
  66.         //添加棋子 
  67.             CubeView view = (CubeView) LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_cube_view, this, false); 
  68.             view.setPosition(new Position(p)); 
  69.             view.setClickedListener(component -> moveChildToBlank(view)); 
  70.             addComponent(view); 
  71.             p.moveToNextPosition(); 
  72.             mChildren[i] = view
  73.         } 
  74.         //最后一個空白棋子 
  75.         mBlankPos = new Position(mSizeX, mSizeY, mSizeX - 1, mSizeY - 1); 
  76.     } 
  77.  
  78.  
  79.  
  80.     public void setData(List<Integer> data) { 
  81.         for (int i = 0; i < mChildSize; i++) { 
  82.             CubeView view = (CubeView) getComponentAt(i); 
  83.             view.setNumber(data.get(i)); 
  84.         } 
  85.     } 
  86.  
  87.     //測量監聽方法 
  88.     @Override 
  89.     public boolean onEstimateSize(int widthEstimatedConfig, int heightEstimatedConfig) { 
  90.         invalidateValues(); 
  91.         //測量子組件的大小 
  92.         measureChildren( widthEstimatedConfig,  heightEstimatedConfig); 
  93.        //關聯子組件的索引與其布局數據 
  94.         for (int idx = 0; idx < getChildCount(); idx++) { 
  95.             CubeView childView = (CubeView) getComponentAt(idx); 
  96.             addChild(childView, idx, EstimateSpec.getSize(widthEstimatedConfig)); 
  97.         } 
  98.         //測量本身大小 
  99.         setEstimatedSize( widthEstimatedConfig,  heightEstimatedConfig); 
  100.  
  101.  
  102.         return true
  103.     } 
  104.  
  105.     private void measureChildren(int widthEstimatedConfig, int heightEstimatedConfig) { 
  106.         for (int idx = 0; idx < getChildCount(); idx++) { 
  107.             CubeView childView = (CubeView) getComponentAt(idx); 
  108.             if (childView != null) { 
  109.                 LayoutConfig lc = childView.getLayoutConfig(); 
  110.                 int childWidthMeasureSpec; 
  111.                 int childHeightMeasureSpec; 
  112.                 if (lc.width == LayoutConfig.MATCH_CONTENT) { 
  113.                     childWidthMeasureSpec = EstimateSpec.getSizeWithMode(lc.width, EstimateSpec.NOT_EXCEED); 
  114.                 } else if (lc.width == LayoutConfig.MATCH_PARENT) { 
  115.                     int parentWidth = EstimateSpec.getSize(widthEstimatedConfig); 
  116.                     int childWidth = parentWidth - childView.getMarginLeft() - childView.getMarginRight(); 
  117.                     childWidthMeasureSpec = EstimateSpec.getSizeWithMode(childWidth, EstimateSpec.PRECISE); 
  118.                 } else { 
  119.                     childWidthMeasureSpec = EstimateSpec.getSizeWithMode(lc.width, EstimateSpec.PRECISE); 
  120.                 } 
  121.  
  122.                 if (lc.height == LayoutConfig.MATCH_CONTENT) { 
  123.                     childHeightMeasureSpec = EstimateSpec.getSizeWithMode(lc.height, EstimateSpec.NOT_EXCEED); 
  124.                 } else if (lc.height == LayoutConfig.MATCH_PARENT) { 
  125.                     int parentHeight = EstimateSpec.getSize(heightEstimatedConfig); 
  126.                     int childHeight = parentHeight - childView.getMarginTop() - childView.getMarginBottom(); 
  127.                     childHeightMeasureSpec = EstimateSpec.getSizeWithMode(childHeight, EstimateSpec.PRECISE); 
  128.                 } else { 
  129.                     childHeightMeasureSpec = EstimateSpec.getSizeWithMode(lc.height, EstimateSpec.PRECISE); 
  130.                 } 
  131.                 childView.estimateSize(childWidthMeasureSpec, childHeightMeasureSpec); 
  132.             } 
  133.         } 
  134.     } 
  135.  
  136.  
  137.     private void measureSelf(int widthEstimatedConfig, int heightEstimatedConfig) { 
  138.         int widthSpce = EstimateSpec.getMode(widthEstimatedConfig); 
  139.         int heightSpce = EstimateSpec.getMode(heightEstimatedConfig); 
  140.         int widthConfig = 0; 
  141.         switch (widthSpce) { 
  142.             case EstimateSpec.UNCONSTRAINT: 
  143.             case EstimateSpec.PRECISE: 
  144.                 int width = EstimateSpec.getSize(widthEstimatedConfig); 
  145.                 widthConfig = EstimateSpec.getSizeWithMode(width, EstimateSpec.PRECISE); 
  146.                 break; 
  147.             case EstimateSpec.NOT_EXCEED: 
  148.                 widthConfig = EstimateSpec.getSizeWithMode(maxWidth, EstimateSpec.PRECISE); 
  149.                 break; 
  150.             default
  151.                 break; 
  152.         } 
  153.  
  154.         int heightConfig = 0; 
  155.         switch (heightSpce) { 
  156.             case EstimateSpec.UNCONSTRAINT: 
  157.             case EstimateSpec.PRECISE: 
  158.                 int height = EstimateSpec.getSize(heightEstimatedConfig); 
  159.                 heightConfig = EstimateSpec.getSizeWithMode(height, EstimateSpec.PRECISE); 
  160.                 break; 
  161.             case EstimateSpec.NOT_EXCEED: 
  162.                 heightConfig = EstimateSpec.getSizeWithMode(maxHeight, EstimateSpec.PRECISE); 
  163.                 break; 
  164.             default
  165.                 break; 
  166.         } 
  167.         setEstimatedSize(widthConfig, heightConfig); 
  168.     } 
  169.  
  170.  
  171.  
  172.     //每個棋子組件的位置及大小 
  173.     @Override 
  174.     public boolean onArrange(int l, int t, int r, int b) { 
  175.  
  176.         for (int idx = 0; idx < getChildCount(); idx++) { 
  177.             Component childView = getComponentAt(idx); 
  178.             Layout layout = axis.get(idx); 
  179.             if (layout != null) { 
  180.                 childView.arrange(layout.positionX, layout.positionY, layout.width, layout.height); 
  181.             } 
  182.         } 
  183.         return true
  184.     } 
  185.  
  186.  
  187.     private void addChild(CubeView component, int id, int layoutWidth) { 
  188.         Layout layout = new Layout(); 
  189.         layout.positionX = xx + component.getMarginLeft(); 
  190.         layout.positionY = yy + component.getMarginTop(); 
  191.         layout.width = component.getEstimatedWidth(); 
  192.         layout.height = component.getEstimatedHeight(); 
  193.         if ((xx + layout.width) > layoutWidth) { 
  194.             xx = 0; 
  195.             yy += lastHeight; 
  196.             lastHeight = 0; 
  197.             layout.positionX = xx + component.getMarginLeft(); 
  198.             layout.positionY = yy + component.getMarginTop(); 
  199.         } 
  200.         axis.put(id, layout); 
  201.         lastHeight = Math.max(lastHeight, layout.height + component.getMarginBottom()); 
  202.         xx += layout.width + component.getMarginRight(); 
  203.         maxWidth = Math.max(maxWidth, layout.positionX + layout.width + component.getMarginRight()); 
  204.         maxHeight = Math.max(maxHeight, layout.positionY + layout.height + component.getMarginBottom()); 
  205.     } 
  206.      
  207.     //點擊棋子后進行位置切換 
  208.     public void moveChildToBlank(@org.jetbrains.annotations.NotNull CubeView child) { 
  209.         Position childPos = child.getPosition(); 
  210.         Position dstPos = mBlankPos; 
  211.         if (childPos.x == dstPos.x && Math.abs(childPos.y - dstPos.y) == 1 || 
  212.                 childPos.y == dstPos.y && Math.abs(childPos.x - dstPos.x) == 1) { 
  213.             child.setPosition(dstPos); 
  214.             //component中沒有對組件進行物理平移的方法 
  215.             //setTranslationX(),setTranslationY()兩個方法沒有 
  216.             child.setTranslationX(dstPos.x * xx); 
  217.             child.setTranslationY(dstPos.y * yy); 
  218.  
  219.             mBlankPos = childPos; 
  220.             mStepCounter.add(); 
  221.         } 
  222.         checkPosition(); 
  223.     } 
  224.  
  225.     /** 
  226.      * 檢查所有格子位置是否正確 
  227.      */ 
  228.     private void checkPosition() { 
  229.         if (mBlankPos.x != mSizeX - 1 || mBlankPos.y != mSizeY - 1) { 
  230.             return
  231.         } 
  232.  
  233.         for (CubeView child : mChildren) { 
  234.             int num = child.getNumber(); 
  235.             int x = child.getPosition().x; 
  236.             int y = child.getPosition().y; 
  237.             if (y * mSizeX + x + 1 != num) { 
  238.                 return
  239.             } 
  240.         } 
  241.  
  242.         if (mFinishListener != null) { 
  243.             mFinishListener.onFinished(mStepCounter.step); 
  244.         } 
  245.         for (CubeView child : mChildren) { 
  246.             child.setClickable(false); 
  247.         } 
  248.     } 
  249.  
  250.     public void setOnFinishedListener(OnFinishListener l) { 
  251.         mFinishListener = l; 
  252.     } 
  253.  
  254.     public interface OnFinishListener { 
  255.         void onFinished(int step); 
  256.     } 
  257.  
  258.     public int getSizeX() { 
  259.         return mSizeX; 
  260.     } 
  261.  
  262.     public int getSizeY() { 
  263.         return mSizeY; 
  264.     } 
  265.  
  266.     /** 
  267.      * 步數統計 
  268.      */ 
  269.     class StepCounter { 
  270.         private int step = 0; 
  271.  
  272.         void add() { 
  273.             step++; 
  274.         } 
  275.  
  276.         void clear() { 
  277.             step = 0; 
  278.         } 
  279.     } 
  280.  
  281.     private StepCounter mStepCounter = new StepCounter(); 
  282.  

棋盤的自定義布局也完成了。棋盤的布局稍微復雜一點,因為需要根據棋盤的大小計算每一個棋子的大小,還需要對棋子進行綁定,尤其是需要對最后一個棋子做空白處理。

然后點擊棋子進行棋子的平移,平移后與其位置進行互換。

第二個坑

鴻蒙小游戲-數字華容道  自定義組件的踩坑記錄-鴻蒙HarmonyOS技術社區

點擊棋子進行位置平移,因為在API里面沒有找到component公共組件下的平移方法,setTranslationX()/setTranslationY()方法,沒有辦法做到組件的物理位置平移,導致大家看到開頭演示的效果,點擊后與空白位置坐了切換但是重新對其進行物理位置賦值的時候沒有辦法去賦值,這個問題困擾了我兩天。

現在還是沒有解決掉,試著想想是不是可以使用TouchEvent事件一個滑動處理,不做點擊事件做滑動事件。

最終現在項目的結構如下:

總結

后面還會繼續去完善,以至于到整個功能可以正常去使用,踩坑還是要踩的,總會有收獲的時候…

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2021-08-25 09:54:51

鴻蒙HarmonyOS應用

2021-11-02 14:55:42

鴻蒙HarmonyOS應用

2020-12-11 12:27:35

鴻蒙HarmonyOS

2020-12-22 11:20:36

鴻蒙HarmonyOS游戲

2021-10-09 14:49:50

鴻蒙HarmonyOS應用

2022-10-17 14:39:12

自定義彈窗組件鴻蒙

2012-11-04 14:54:24

2013-10-15 09:48:03

C++Lambda函數式編程

2022-04-24 15:17:56

鴻蒙操作系統

2023-02-20 15:20:43

啟動頁組件鴻蒙

2021-11-01 10:21:36

鴻蒙HarmonyOS應用

2021-12-24 15:46:23

鴻蒙HarmonyOS應用

2017-09-25 16:55:35

2022-02-16 15:25:31

JS代碼Canvas鴻蒙

2022-07-15 16:45:35

slider滑塊組件鴻蒙

2021-09-15 10:19:15

鴻蒙HarmonyOS應用

2022-06-30 14:02:07

鴻蒙開發消息彈窗組件

2022-10-26 15:54:46

canvas組件鴻蒙

2022-10-25 15:12:24

自定義組件鴻蒙

2022-07-06 20:24:08

ArkUI計時組件
點贊
收藏

51CTO技術棧公眾號

欧美成人激情在线| 欧美精品在线观看播放| 欧美日韩国产一二| 中文字幕日本视频| 亚欧美无遮挡hd高清在线视频| 日韩一区二区精品在线观看| 日韩欧美视频网站| 岛国视频一区免费观看| 天堂中文视频在线| 直接在线观看的三级网址| 99麻豆久久久国产精品免费| 国产97免费视| 久久久美女视频| 中文字幕精品影院| 日韩一区二区精品| 日本888xxxx| 欧美xxx黑人xxx水蜜桃| 国产欧美一区二区精品秋霞影院| yellow视频在线观看一区二区| 无码人妻精品一区二区蜜桃色欲| 欧美久久视频| 在线观看免费高清视频97| 国产精品亚洲一区二区无码| 草莓视频成人appios| 五月婷婷另类国产| 亚洲av首页在线| eeuss影院www在线观看| 99久久免费精品| 96国产粉嫩美女| 中文字幕人妻色偷偷久久| 国产日韩一区| 久久久久久久久网站| 国产精品精品软件男同| 国产一区二区三区四区五区传媒 | 一区二区三区欧美成人| 三区在线视频| caoporn国产精品| 91在线精品观看| 国产精品国产三级国产aⅴ| 亚洲深夜av| 久久乐国产精品| 黑人巨大精品一区二区在线| 欧美激情成人| 色七七影院综合| 免费观看a级片| 九九视频精品全部免费播放| 日韩av在线资源| 日本精品一二三| 日本一区二区乱| 激情网站在线| 久久婷婷成人综合色| 国产精选在线观看91| 国产后入清纯学生妹| 久久99国产精品麻豆| 国产精品热视频| 美女黄页在线观看| 免费观看在线综合| 国产精品一区二区三区久久| 中文字幕+乱码+中文乱码www| 天堂资源在线中文精品| 国产成人高潮免费观看精品| 天天操夜夜操视频| 可以看av的网站久久看| 国产999精品久久久| 夜夜躁日日躁狠狠久久av| 日韩精品电影一区亚洲| 国产精品一区av| 一级片视频网站| 国精产品一区一区三区mba桃花| 成人免费直播live| 国产av无码专区亚洲av麻豆| 国产精品影视在线| 国产亚洲欧美一区二区| 天天干,夜夜爽| 2024国产精品| 色噜噜狠狠一区二区三区| 1769在线观看| 一区二区三区美女视频| 国产v片免费观看| 亚洲美免无码中文字幕在线| www.色在线| 一本久久综合亚洲鲁鲁五月天| 992kp快乐看片永久免费网址| 九九热这里有精品| 日韩情涩欧美日韩视频| 人妻丰满熟妇av无码久久洗澡| 精品久久综合| 欧美成人在线免费| 天堂а√在线中文在线新版| 美女视频网站黄色亚洲| 91久久大香伊蕉在人线| 视频三区在线观看| 一区视频在线播放| 国产婷婷一区二区三区| 丰满少妇一区| 亚洲成人久久一区| 国产精品毛片一区二区| 亚洲综合激情在线| 日本高清不卡的在线| 国产免费无遮挡| 91色porny在线视频| 日本福利视频导航| 台湾佬中文娱乐网欧美电影| 欧美精品亚洲二区| 91av在线免费| 欧美 日韩 国产 一区| 人九九综合九九宗合| av老司机久久| 国产蜜臀97一区二区三区| 日韩视频 中文字幕| 偷拍精品精品一区二区三区| 日韩精品中文字幕一区| 亚洲精品成人av久久| 亚洲经典在线| 91久久久久久久久久| 三级做a全过程在线观看| 亚洲视频在线一区| 成年人在线观看视频免费| 99精品国产一区二区三区2021 | 亚洲成人一区| 日本一区免费视频| 91免费版网站在线观看| 成人午夜影视| 天天做天天摸天天爽国产一区| 成人黄色一级大片| 狠狠做深爱婷婷综合一区| 九九久久国产精品| 亚洲天堂网在线观看视频| 99re8在线精品视频免费播放| 欧洲xxxxx| 国产91欧美| 国产亚洲人成a一在线v站| 日产精品久久久久| 国产成人精品亚洲777人妖| 亚洲开发第一视频在线播放| 欧美momandson| 亚洲激情成人网| 国产一级片播放| 国产福利精品导航| 一区二区三区日韩视频| 精品福利在线| 正在播放欧美一区| 波多野结衣高清在线| 久久久蜜桃精品| 欧美黄网站在线观看| 欧美绝顶高潮抽搐喷水合集| 国模精品视频一区二区三区| www.久久精品.com| 亚洲精品美腿丝袜| 久久一区免费| 中文字幕在线视频一区二区| 女仆av观看一区| 久久久综合免费视频| 欧美一级特黄aaaaaa| 亚洲图片自拍偷拍| 欧美做受高潮中文字幕| 一区免费在线| 国内精品二区| 99色在线观看| 日韩成人av网| 中文字幕一区在线播放| 久久精品视频免费观看| 激情综合网俺也去| 操欧美老女人| 成人福利网站在线观看11| 天堂аⅴ在线地址8| 在线不卡一区二区| 国产波霸爆乳一区二区| 国产成人三级在线观看| 蜜臀av色欲a片无码精品一区| 国产精品白丝一区二区三区| 亚州成人av在线| 男人久久精品| 欧美日韩国产综合一区二区| 欧美激情精品久久久久久免费| 国产精品一卡二卡在线观看| 久久精品xxx| 西野翔中文久久精品国产| 国产精品9999| www.在线视频| 欧美一区二区三区免费观看视频| 国产无码精品久久久| 91社区在线播放| www.日本一区| 国产综合亚洲精品一区二| 久久久一本精品99久久精品| 丁香久久综合| 久久青草福利网站| av电影在线观看网址| 日韩午夜激情视频| 欧美特黄aaaaaa| 综合av第一页| 在线观看国产三级| 国产h在线观看| 韩日av一区二区| 给我免费播放片在线观看| 国产videos久久| 91在线网站视频| 欧美办公室脚交xxxx| 在线观看91久久久久久| 性生活免费网站| 91传媒视频在线播放| 免费中文字幕在线| 国产日产欧美一区二区三区| 成年人看片网站| 日韩激情av在线| 800av在线免费观看| 欧美日一区二区| 国产日产精品一区二区三区四区 | 国产精品主播视频| 91av久久| 美女福利精品视频| 成人影视在线播放| 日韩av影院在线观看| 99久久精品国产成人一区二区| 欧美性xxxxx极品娇小| 欧洲第一无人区观看| 国产精品色婷婷久久58| 在线观看国产免费视频| 国产一区二区导航在线播放| 国产三级三级三级看三级| 亚洲国产激情| 久久天天东北熟女毛茸茸| 日韩理论电影| 欧美精品一区在线发布| 韩国女主播一区二区三区| 91欧美视频网站| 欧美aaaaaaaa| 国产精品99免视看9| 在线手机中文字幕| 欧美激情啊啊啊| 在线免费观看污| 日韩亚洲一区二区| av在线二区| 亚洲天堂成人在线视频| 天堂中文字幕在线| 亚洲成人久久电影| 好男人www在线视频| 91精品国产综合久久小美女| 亚洲天堂视频在线| 欧美日韩国产高清一区二区| 国产精品日韩欧美一区二区| 成人片在线看| 久久精品国产成人精品| 在线观看黄色av| 一区二区三区视频免费| 国产精品视频一区二区久久| 日本成人在线电影网| 3d蒂法精品啪啪一区二区免费| 96sao精品免费视频观看| 69堂精品视频| 91超薄丝袜肉丝一区二区| 欧美色图片你懂的| 中文字幕精品一区二区精| 欧美午夜电影网| 在线观看中文字幕2021| 欧美日韩精品一二三区| 影音先锋黄色网址| 欧美精品日韩一区| 国产强伦人妻毛片| 欧美草草影院在线视频| 欧美一区二区三区成人片在线| 精品卡一卡二卡三卡四在线| 男人的天堂a在线| 亚洲精品99999| 欧美视频综合| 伊人久久免费视频| 日本视频在线播放| 日韩网站免费观看| 在线观看av免费| 久久久亚洲精选| 在线天堂资源| 国产精品久久久久久婷婷天堂| 色999久久久精品人人澡69| 51成人做爰www免费看网站| 国产精品极品| 日本高清一区| 一级毛片免费高清中文字幕久久网| 青草网在线观看| 亚洲影音一区| 成人性生交免费看| 高清在线不卡av| 欧美多人猛交狂配| 亚洲日本丝袜连裤袜办公室| 国产精品99re| 欧美亚洲国产一区二区三区| 精品国产九九九| 精品在线观看国产| 美女羞羞视频在线观看| 欧美极品在线视频| av激情成人网| 国产成人精品福利一区二区三区| 亚洲成aⅴ人片久久青草影院| 亚洲无玛一区| 亚洲青涩在线| 亚洲视频一二三四| 99久久精品免费| 亚洲一二三四五六区| 欧美日韩另类字幕中文| 国产又粗又猛又黄又爽| 亚洲精品国产精品乱码不99按摩 | 可以在线看黄的网站| 噜噜噜91成人网| 在线成人免费av| 欧美gayvideo| 日韩欧美一级二级三级久久久| 亚洲国产精品久久久久久6q| 一区二区三区视频免费| 超碰资源在线| 国产精品永久免费视频| 午夜a一级毛片亚洲欧洲| 国产精品av免费观看| 免费在线观看一区二区三区| 成人手机在线免费视频| 亚洲理论在线观看| 欧美高清69hd| 日韩精品视频在线观看免费| 午夜小视频福利在线观看| 国产精品日韩电影| 西野翔中文久久精品国产| av在线com| 国模大尺度一区二区三区| 精品一区二区三区蜜桃在线| 欧美色另类天堂2015| 亚洲欧美激情国产综合久久久| 日韩中文字幕免费| 亚洲成人不卡| 久草精品电影| 在线日本成人| 黄色国产在线视频| 亚洲蜜桃精久久久久久久| 亚洲特级黄色片| 亚洲区免费影片| 忘忧草在线影院两性视频| 国产精品一区二区免费看| 最新国产精品久久久| 国产女同无遮挡互慰高潮91| 欧美国产成人在线| 免费无码国产精品| 亚洲欧美激情视频| a一区二区三区| 美女黄毛**国产精品啪啪| 亚洲精品影院在线观看| 亚洲av成人片无码| 亚洲国产精品综合小说图片区| www黄色网址| 久久69精品久久久久久久电影好 | 在线观看日本中文字幕| 欧美午夜片在线免费观看| 欧美新色视频| 日本精品视频在线播放| 奇米狠狠一区二区三区| 男人搞女人网站| 国产欧美日韩在线观看| 日韩乱码一区二区三区| 色偷偷偷综合中文字幕;dd| 国产一区二区三区四区五区3d | 中文字幕一区二区人妻电影丶| 亚洲1区2区3区视频| 四虎免费在线观看| 欧美在线视频一区| 国产精品手机在线播放| 8x8x最新地址| 中文字幕一区二区三中文字幕| 国产女人高潮毛片| 欧美黄网免费在线观看| 秋霞蜜臀av久久电影网免费| 99re在线视频免费观看| 欧美激情一区不卡| 亚洲精品无码久久久久久| 噜噜噜狠狠夜夜躁精品仙踪林| 国产成人一区二区三区别| 成人99免费视频| 一级黄色大片视频| 最近2019中文字幕第三页视频| 国产电影一区| 91免费黄视频| 久久精品一二三| 国产又大又长又粗| 欧美激情一区二区三区久久久| 日本中文字幕在线一区| 久久久国产欧美| 亚洲精品免费在线观看| 五月婷中文字幕| 国产男人精品视频| 欧美在线国产| 女尊高h男高潮呻吟| 欧美精品乱码久久久久久按摩| 懂色av一区| 亚洲精品乱码视频| 粉嫩一区二区三区在线看| youjizz在线视频| 久久综合久中文字幕青草 | 欧美一区亚洲二区| 国产乱码精品1区2区3区| 国产精品免费精品一区| 久久成人综合视频| 免费看成人吃奶视频在线| 亚洲三级在线视频| 色综合激情久久|