側滑1

来源:http://www.cnblogs.com/wangfengdange/archive/2016/01/31/5173559.html
-Advertisement-
Play Games

如圖是效果圖 我用的是SlidingMenu-master框架來實現的 左邊的是側滑界面是一個fragment,右邊是一個主界面fragment,在主界面中用的是一個ViewPager來進行切換,自定義個NoScrollViewPager(不能左右劃的ViewPager) 如下是主界面的代碼 pac


如圖是效果圖

                                  

 

我用的是SlidingMenu-master框架來實現的

左邊的是側滑界面是一個fragment,右邊是一個主界面fragment,在主界面中用的是一個ViewPager來進行切換,自定義個NoScrollViewPager(不能左右劃的ViewPager)

如下是主界面的代碼

package com.demo.sb.main;

import com.demo.sb.mainfram.ContentFragment;
import com.demo.sb.mainfram.LeftMenuFragment;
import com.demo.suibian.R;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity;

import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Window;

/**
 * 主界面
 * 
 * @author Administrator
 * 
 */
public class Activity_Main extends SlidingFragmentActivity {

    private static final String FRAGMENT_LEFT_MENU = "fragment_left_menu";
    private static final String FRAGMENT_CONTENT = "fragment_content";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        setBehindContentView(R.layout.left_menu);// 設置側邊欄
        SlidingMenu slidingMenu = getSlidingMenu();// 獲取側邊欄對象
        // 設置全屏觸摸
        slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);

        int width = getWindowManager().getDefaultDisplay().getWidth();

        slidingMenu.setBehindOffset(width * 200 / 500);// 設置預留屏幕的寬度

        initFragment();
        
    }
    /*
     * 初始化fragment,將fragment的數據填充給佈局文件
     */
    private void initFragment() {
        FragmentManager fManager = getSupportFragmentManager();
        //開啟事務
        FragmentTransaction transaction = fManager.beginTransaction();
        transaction.replace(R.id.fl_left_menu, new LeftMenuFragment(),
                FRAGMENT_LEFT_MENU);
        transaction.replace(R.id.fl_content, new ContentFragment(),
                FRAGMENT_CONTENT);
        transaction.commit();// 提交事務
    }

    
    
    
    // 獲取側邊欄fragment
    public LeftMenuFragment getLeftMenuFragment() {
        FragmentManager fm = getSupportFragmentManager();
        LeftMenuFragment fragment = (LeftMenuFragment) fm
                .findFragmentByTag(FRAGMENT_LEFT_MENU);

        return fragment;
    }

    // 獲取主頁面fragment
    public ContentFragment getContentFragment() {
        FragmentManager fm = getSupportFragmentManager();
        ContentFragment fragment = (ContentFragment) fm
                .findFragmentByTag(FRAGMENT_CONTENT);

        return fragment;
    }
}

R.layout.activity_main

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fl_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</FrameLayout>
View Code

R.layout.left_menu

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fl_left_menu"
    android:descendantFocusability="blocksDescendants"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</FrameLayout>
View Code
package com.demo.sb.mainfram;

import java.util.ArrayList;

import com.demo.suibian.R;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;

public class ContentFragment extends Fragment{
    private RadioGroup rg_group;
    private ViewPager mViewPager;
    private ArrayList<BasePager> mPagerList;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.fragment_content, null, false);
    }
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
        rg_group =(RadioGroup)getActivity().findViewById(R.id.rg_group);
        mViewPager=(ViewPager)getActivity().findViewById(R.id.vp_content);
        
        initData();
    }

    private void initData() {
        // TODO Auto-generated method stub
        rg_group.check(R.id.rb_one);
        //初始化3個子頁面
        mPagerList = new ArrayList<BasePager>();
        mPagerList.add(new OnePager(getActivity()));
        mPagerList.add(new TwoPager(getActivity()));
        mPagerList.add(new ThreePager(getActivity()));
        
        mViewPager.setAdapter(new ContentAdapter());
        
        rg_group.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            
            @Override
            public void onCheckedChanged(RadioGroup arg0, int arg1) {
                // TODO Auto-generated method stub
                switch (arg1) {
                case R.id.rb_one:
                    //mViewPager.setCurrentItem(0) 設置當前的頁面
                    mViewPager.setCurrentItem(0, false);// 去掉切換頁面的動畫
                    break;
                case R.id.rb_two:
                    mViewPager.setCurrentItem(1, false);
                    break;
                case R.id.rb_three:
                    mViewPager.setCurrentItem(2, false);
                    break;

                default:
                    break;
                }
            }
        });
        
        mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
            //獲取當前被選中的頁面
            @Override
            public void onPageSelected(int arg0) {
                // TODO Auto-generated method stub
                mPagerList.get(arg0).initData();
            }
            
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub
                
            }
            
            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub
                
            }
        });
        mPagerList.get(0).initData();//初始化首頁數據
    }
    
    class ContentAdapter extends PagerAdapter{

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return mPagerList.size();
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            // TODO Auto-generated method stub
            return arg0 == arg1;
        }
        
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // TODO Auto-generated method stub
            BasePager pager = mPagerList.get(position);
            container.addView(pager.mRootView);
            //pager.initData();//初始化數據.... 不要放在這初始化數據,否則會預載入下個頁面
            return pager.mRootView;
        }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // TODO Auto-generated method stub
            container.removeView((View) object);
        }
    }
}
<?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:orientation="vertical" >

    <com.demo.sb.widget.NoScrollViewPager
        android:id="@+id/vp_content"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <RadioGroup
        android:id="@+id/rg_group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/bottom_tab_bg"
        android:orientation="horizontal" >

        <RadioButton
            android:id="@+id/rb_one"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:button="@null"
            android:drawablePadding="2dp"
            android:drawableTop="@drawable/btn_tab_home_selector"
            android:gravity="center"
            android:padding="3dp"
            android:text="第一個"
            android:textColor="@drawable/btn_tab_text_selector" />

        <RadioButton
            android:id="@+id/rb_two"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:button="@null"
            android:drawablePadding="2dp"
            android:drawableTop="@drawable/btn_tab_home_selector"
            android:gravity="center"
            android:padding="3dp"
            android:text="第二個"
            android:textColor="@drawable/btn_tab_text_selector" />

        <RadioButton
            android:id="@+id/rb_three"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:button="@null"
            android:drawablePadding="2dp"
            android:drawableTop="@drawable/btn_tab_home_selector"
            android:gravity="center"
            android:padding="3dp"
            android:text="第三個"
            android:textColor="@drawable/btn_tab_text_selector" />
    </RadioGroup>

</LinearLayout>
package com.demo.sb.mainfram;

import com.demo.sb.main.Activity_Main;
import com.demo.suibian.R;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;

import android.app.Activity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.TextView;

/**
 * 主頁面下的3個子頁面
 * 
 * @author Administrator
 * 
 */
public class BasePager {
    public Activity mActivity;
    public View mRootView;// 佈局對象
    public TextView tvTitle;// 標題對象
    public FrameLayout flContent;// 內容
    public ImageButton btnMenu;// 菜單按鈕

    public BasePager(Activity activity) {
        mActivity = activity;
        initView();
    }

    /**
     * 初始化佈局
     */
    private void initView() {
        // TODO Auto-generated method stub
        mRootView = View.inflate(mActivity, R.layout.base_pager, null);

        tvTitle = (TextView) mRootView.findViewById(R.id.tv_title);
        flContent = (FrameLayout) mRootView.findViewById(R.id.fl_content);
        btnMenu = (ImageButton) mRootView.findViewById(R.id.btn_menu);

        btnMenu.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                toggleSlidingMenu();
            }
        });
    }

    /**
     * 切換SlidingMenu的狀態
     * 
     */
    protected void toggleSlidingMenu() {
        // TODO Auto-generated method stub
        Activity_Main main = (Activity_Main) mActivity;
        SlidingMenu slidingMenu = main.getSlidingMenu();
        slidingMenu.toggle();// 切換狀態,顯示時隱藏,隱藏時顯示
    }

    /**
     * 初始化數據
     */
    public void initData() {

    }

    /**
     * 設置側邊欄開啟或是關閉
     */

    public void setSlidingMenuEnable(boolean enable) {
        Activity_Main main = (Activity_Main) mActivity;
        SlidingMenu slidingMenu = main.getSlidingMenu();
        if (enable) {
            slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
        } else {
            slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);
        }
    }
}
<?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:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/title_red_bg" >

        <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="隨便寫的"
            android:textColor="#fff"
            android:textSize="22sp" />

        <ImageButton
            android:id="@+id/btn_menu"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:contentDescription="@null"
            android:layout_centerVertical="true"
            android:layout_marginLeft="5dp"
            android:background="@null"
            android:src="@drawable/back" />

    </RelativeLayout>

    <FrameLayout
        android:id="@+id/fl_content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
    </FrameLayout>

</LinearLayout>
View Code
package com.demo.sb.mainfram;

import java.util.ArrayList;

import com.demo.suibian.R;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;

import android.app.Activity;
import android.graphics.Bitmap;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.Toast;

public class TwoPager extends BasePager implements OnClickListener {

    private Button btn_two_toast;
    private ViewPager mViewPager;
    
    public static final String[] IMAGES = new String[] {
            "http://image.tianjimedia.com/uploadImages/2012/067/ORQR14KR5DDC.jpg",
            "http://image.tianjimedia.com/uploadImages/2012/067/X6BEO07U962E.jpg",
            "http://image.tianjimedia.com/uploadImages/2012/067/F9X84V2ST716.jpg",
            "http://image.tianjimedia.com/uploadImages/2012/067/RY445ENQ16BH.jpg",
            "http://image.tianjimedia.com/uploadImages/2012/067/74KAJLN0JL95.jpg", };
    private ImageLoader loader;
    private DisplayImageOptions options;
    
    private static final int[] mImageIds = new int[]{R.drawable.a,R.drawable.c,R.drawable.d};
    private ArrayList<ImageView> mImageViewList;
    
    public TwoPager(Activity activity) {
        super(activity);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void initData() {
        // TODO Auto-generated method stub
        System.out.println("初始化第二個界面。。。");

        loader = ImageLoader.getInstance();
        options = new DisplayImageOptions.Builder()
                .showImageForEmptyUri(R.drawable.ic_empty)
                .showImageOnFail(R.drawable.ic_error)
                .resetViewBeforeLoading(true).cacheInMemory(true)
                .imageScaleType(ImageScaleType.EXACTLY)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .displayer(new FadeInBitmapDisplayer(300)).build();
        setSlidingMenuEnable(true);// 打開側邊欄

        tvTitle.setText("第二個界面");
        View view = View.inflate(mActivity, R.layout.twopager, null);

        flContent.addView(view);
        btn_two_toast = (Button) view.findViewById(R.id.btn_two_toast);
        btn_two_toast.setOnClickListener(this);

        mViewPager = (ViewPager) view.findViewById(R.id.vp_two_viewpager);
        mViewPager.setAdapter(new ViewAdapter());
        //initView();
        //mViewPager.setAdapter(new GuideAdapter());
    }
    
    private void initView(){
        mImageViewList = new ArrayList<ImageView>();
        for (int i = 0; i < mImageIds.length; i++) {
            ImageView imageView = new ImageView(mActivity);
            imageView.setBackgroundResource(mImageIds[i]);
            mImageViewList.add(imageView);
        }
    }
    
    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        switch (arg0.getId()) {
        case R.id.btn_two_toast:

            Toast.makeText(mActivity, "dddddddddd", Toast.LENGTH_SHORT).show();

            break;

        default:
            break;
        }
    }

    /**
     * PagerAdapter 的適配器
     * 
     * @author Administrator
     * 
     */
    class ViewAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return IMAGES.length;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            // TODO Auto-generated method stub
            return arg0 == arg1;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // TODO Auto-generated method stub
            System.out.println("dd");
            ImageView imageView = new ImageView(mActivity);
            imageView.setScaleType(ScaleType.FIT_XY);
            loader.displayImage(IMAGES[position], imageView, options);
            container.addView(imageView);
            return imageView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // TODO Auto-generated method stub
            container.removeView((View) object);
        }
    }
    
    /**
     * 
     * @author Administrator
     *
     */
    class GuideAdapter extends PagerAdapter{

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return mImageIds.length;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            // TODO Auto-generated method stub
            return arg0 == arg1;
        }
        
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // TODO Auto-generated method stub
            container.addView(mImageViewList.get(position));
            return mImageViewList.get(position);
        }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // TODO Auto-generated method stub
            container.removeView((View) object);
        }
    }
}
<?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:orientation="vertical" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="hello word" />

    <Button
        android:id="@+id/btn_two_toast"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="200dp" >

        <com.demo.sb.widget.HorizonViewPager
            android:id="@+id/vp_two_viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>
    

</LinearLayout>
View Code

自定義的ViewPager

package com.demo.sb.widget;

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * 不能左右劃的ViewPager
 * 
 * @author Administrator
 * 
 */
public class NoScrollViewPager extends ViewPager {

    public NoScrollViewPager(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public NoScrollViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    // 表示事件是否攔截, 返回false表示不攔截, 可以讓嵌套在內部的viewpager相應左右劃的事件
    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        return false;
    }

    /**
     * 重寫onTouchEvent事件,什麼都不用做
     */
    @Override
    public boolean onTouchEvent(MotionEvent arg0) {
        return false;
    }
}
package com.demo.sb.widget;

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * 子頁簽的水平滑動ViewPager,暫時不用
 * @author Administrator
 *
 */
public class HorizonViewPager extends ViewPager {

    public HorizonViewPager(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public HorizonViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }
    
    /**
     * 事件的分發,請求父控制項及祖宗事件是否攔截事件
     */
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        if(getCurrentItem() != 0){
            getParent().requestDisallowInterceptTouchEvent(true);
        }else {
            getParent().requestDisallowInterceptTouchEvent(false);
        }
        return super.dispatchTouchEvent(ev);
    }
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 安全性,總是一個不可忽視的問題。許多人都承認這點,但是卻很少有人真的認真地對待它。所以我們列出了這個清單,讓你在將你的應用部署到生產環境來給千萬用戶使用之前,做一個安全檢查。 以下列出的安全項,大多都具有普適性,適用於除了Node.js外的各種語言和框架。但是,其中也包含一些用Node.js寫
  • 寫了一個slideDoor,reset.css就不放上來了,自行添加吧! 1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>slideDoor</title> 7 <link type="text/css"
  • 一,效果圖。 二,工程圖。 三,代碼。 RootViewController.m #import "RootViewController.h" @interface RootViewController () @end @implementation RootViewController - (id
  • 首先申明下,本文為筆者學習《OpenGL ES應用開發實踐指南(Android捲)》的筆記,涉及的代碼均出自原書,如有需要,請到原書指定源碼地址下載。 《OpenGL ES學習筆記(二)——平滑著色、自適應寬高及三維圖像生成》中闡述的平滑著色、自適應寬高是為了實現在移動端模擬真實場景採用的方法,並且...
  • 【原】AFNetworking源碼閱讀(五) 本文轉載請註明出處 —— polobymulberry-博客園 1. 前言 上一篇中提及到了Multipart Request的構建方法- [AFHTTPRequestSerializer multipartFormRequestWithMethod:U
  • 這一篇主要介紹使用AFN如何訪問HTTPS網站以及這些做法的實現原理,還有介紹AFN的網路狀態監測部分AFNetworkReachabilityManager,這個模塊會和蘋果官方發Reachability框架做一個對比。 本文所有的代碼都運行在iOS9.2的模擬器上,並且在info.plist對A
  • 本文節選自《Android Studio實用指南》 第4章第27節 作者: 畢小朋 目前本書已上傳到百度閱讀, 在百度中搜索[Anroid Studio實用指南]便可以找到本書. 什麼是演示模式? 顧名思義,當你想給別人演示你的代碼時就會用到這個演示模式. 演示模式的特點就是全屏,開啟免打擾模式,
  • <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...