Android 可横竖滑动的双向表格

Android -- 自定义实现横竖双向滚动的列表(ListView)布局 终于忙完手头上的工作了,难得有时间再唠叨一篇博客。在刚刚处理完的项目需求中,有一个小需求是客户要求查询出的所有数据一屏显示,如果显示不全,要做成可以左右滑动查看的形式(PS:原来的布局仅仅是一个ListView,然后显示几个重要数据,类似于数据表格)。既然客户要求了,那咱作为程序猿的就得赶紧实现啊(相信很多程序猿小伙伴都有这种经历,需求一遍一遍的提,一遍一遍的改,今天这个样,明天那个样,心里每天都 阅读详情

前段时间做个项目,要用到一个横向滑动的表格,顺手百度了一下,看到一位哥们的思路挺不错(http://www.javaapk.com/source/4374.html),参考了一下其中的思路,进行了一定的封装和优化。

封装后还没进行过较为详细的测试,如果遇见有bug或者有优化的建议的话,可随时联系我。

其实整个横竖表格的原理实现,竖向的滑动的话,就是listview的滑动,横向的话,则在listview的item里面利用HorizontalScrollView实现横向滑动,然后加以控制,当某一个item里的HorizontalScrollView发生横向滑动的时候,就把所有的item里的HorizontalScrollView也滑动到对应的位置。

我把这个listview和标题行封装到了一个LinearLayout中,封装成了VHTableView。

先看一下怎么用

布局xml如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
   >

<com.demo.zj.vhtableview.VHTableView
    android:id="@+id/vht_table"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

</com.demo.zj.vhtableview.VHTableView>
</RelativeLayout>
布局文件很简单,就这个自定义的view。

接着在activity里的调用,也很简单

<span style="white-space:pre">	</span>VHTableView vht_table=(VHTableView)findViewById(R.id.vht_table);
<span style="white-space:pre">	</span>VHTableAdapter tableAdapter=new VHTableAdapter(this,titleData,contentData);//titleData,contentData这两个数据源自己设置..
        //vht_table.setFirstColumnIsMove(true);//设置第一列是否可移动,默认不可移动
        //vht_table.setShowTitle(false);//设置是否显示标题行,默认显示
        vht_table.setAdapter(tableAdapter);
里面的VHtableAdapter是实现了VHBaseAdapter接口的类,接着来看VHBaseAdapter接口

import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


public interface VHBaseAdapter {

    //表格内容的行数,不包括标题行
    public int getContentRows() ;

    //列数
    public int getContentColumn();

    //标题的view,这里从0开始,这里要注意,一定要有view返回去,不能为null,每一行
    // 各列的宽度就等于标题行的列的宽度,且边框的话,自己在这里和下文的表格单元格view里面设置
    public View getTitleView(int columnPosition, ViewGroup parent);

    //表格正文的view,行和列都从0开始,宽度的话在载入的时候,默认会是以标题行各列的宽度,高度的话自适应
    public View getTableCellView(int contentRow, int contentColum, View view, ViewGroup parent);


    public Object getItem(int contentRow) ;

    //每一行被点击的时候的回调
    public void OnClickContentRowItem(int row, View convertView);
}
接下来看VHTableView的具体实现,具体代码如下:




import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.demo.zj.R;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


public class VHTableView extends LinearLayout implements HListViewScrollView.ScrollChangedListener{


    private Context context;
    private LayoutInflater inflater;
    //是否显示标题行
    private boolean showTitle;
    //第一列是否可移动
    private boolean firstColumnIsMove;


    //用于显示表格正文内容
    private ListView listView;


    //存放标题行中的每一列的宽度,所有的行里的每一列都是基于标题行的每一列的宽度,都跟标题行的每一列的宽度相等
    private HashMap<String ,Integer> widthMap=new HashMap<>();

    //存放所有的HScrollView
    protected List<HListViewScrollView> mHScrollViews =new ArrayList<HListViewScrollView>();



    public VHTableView(Context context) {
        this(context,null);
    }

    public VHTableView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    private void init() {
        this.inflater = LayoutInflater.from(context);
        //默认显示标题行
        showTitle=true;
        //默认第一列不可滑动
        firstColumnIsMove=false;
    }

    //设置是否显示标题
    public void setShowTitle(boolean showTitle) {
        this.showTitle = showTitle;
    }

    //设置第一列是否可以滑动
    public void setFirstColumnIsMove(boolean firstColumnIsMove) {
        this.firstColumnIsMove = firstColumnIsMove;
    }



    //设置adapter
    public void setAdapter(final VHBaseAdapter conentAdapter) {
        //清除各原有数据
        cleanup();
        //载入标题行
        initTitles(conentAdapter);
        //载入表格正文
        initContentList(conentAdapter);
        if(!showTitle){
            //假如设置了不显示标题行,在这里隐藏掉
          getChildAt(0).setVisibility(View.GONE);
        }

    }
    public void cleanup(){
        removeAllViews();
        widthMap.clear();
        mHScrollViews.clear();
    }

    private void initTitles(VHBaseAdapter conentAdapter) {
        View titleView=inflater.inflate(R.layout.vhtable_item_listview,this,false);
        LinearLayout  ll_firstcolumn=(LinearLayout)titleView.findViewById(R.id.ll_firstcolumn);
        int i=0;
        if(firstColumnIsMove){
            //假如设置是可移动的,则把不可移动的部分ll_firstcolumn隐藏掉,把所有数据都加在HListViewScrollView中
            ll_firstcolumn.setVisibility(View.GONE);
        }else {
            //假如是设置了第一列不可移动的,则把第一列的数据加到ll_firstcolumn中,其余的都加到HListViewScrollView中
            ll_firstcolumn.removeAllViews();
            View view =conentAdapter.getTitleView(0,ll_firstcolumn);
            //测量view的高度,都采用自适应的模式测量
            view.measure(0,0);
            ll_firstcolumn.addView(view, LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
            //存起来以便设置表格正文的时候进行宽度设置
            widthMap.put("0",view.getMeasuredWidth());
            //之后的titleview就都放在CHListViewScrollView中,因为0 title已经设置了,所以从1开始
             i=1;
        }


            HListViewScrollView chs_datagroup=(HListViewScrollView)titleView.findViewById(R.id.chs_datagroup);
            //把CHListViewScrollView加入管理
            addHViews(chs_datagroup);

            LinearLayout ll_datagroup=(LinearLayout)titleView.findViewById(R.id.ll_datagroup);

            ll_datagroup.removeAllViews();
            for(;i<conentAdapter.getContentColumn();i++){
                View view=conentAdapter.getTitleView(i,ll_datagroup);
                view.measure(0,0);
                ll_datagroup.addView(view,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
                widthMap.put(i+"", view.getMeasuredWidth());
            }
            addView(titleView);

    }




    private void initContentList(VHBaseAdapter conentAdapter) {
        listView =new ListView(context);
        //设置间隔线为0,以便在view中自己定义间隔线
        listView.setDividerHeight(0);
        ContentAdapter adapter=new ContentAdapter(conentAdapter);
        listView.setAdapter(adapter);
        addView(listView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }


    public void addHViews(final HListViewScrollView hScrollView) {
        if(!mHScrollViews.isEmpty()) {
            int size = mHScrollViews.size();
            HListViewScrollView scrollView = mHScrollViews.get(size - 1);
            final int scrollX = scrollView.getScrollX();
            //这是给第一次满屏,或者快速下滑等情况时,新创建的会再创建一个convertView的时候,把这个新进入的convertView里的HListViewScrollView移到对应的位置
            if(scrollX != 0) {
                listView.post(new Runnable() {
                    @Override
                    public void run() {
                        //在主线程中去移动到对应的位置
                        hScrollView.scrollTo(scrollX, 0);
                    }
                });
            }
        }
        hScrollView.setScrollChangedListener(this);
        mHScrollViews.add(hScrollView);
    }


    private HListViewScrollView currentTouchView;
    @Override
    public void setCurrentTouchView(HListViewScrollView currentTouchView) {
        this.currentTouchView=currentTouchView;
    }

    @Override
    public HListViewScrollView getCurrentTouchView() {
        return currentTouchView;
    }

    @Override
    public void onUIScrollChanged(int l, int t, int oldl, int oldt) {
        for(HListViewScrollView scrollView : mHScrollViews) {
            //防止重复滑动
            if(currentTouchView != scrollView)
                scrollView.smoothScrollTo(l, t);
        }
    }

    public class  ContentAdapter extends BaseAdapter {
        private VHBaseAdapter conentAdapter;

        public ContentAdapter(VHBaseAdapter conentAdapter) {
            this.conentAdapter=conentAdapter;
        }

        @Override
        public int getCount() {
            return conentAdapter.getContentRows();
        }

        @Override
        public Object getItem(int position) {
            return conentAdapter.getItem(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View convertView, final ViewGroup parent) {
            ViewHolder viewHolder;
            int maxHeight=0;
            if(null==convertView){
                convertView=inflater.inflate(R.layout.vhtable_item_listview,parent,false);

                HListViewScrollView chs_datagroup=(HListViewScrollView)convertView.findViewById(R.id.chs_datagroup);
                //把CHListViewScrollView加入管理
                addHViews(chs_datagroup);
                viewHolder=new ViewHolder();
                viewHolder.views = new View[conentAdapter.getContentColumn()];
                viewHolder.ll_firstcolumn=(LinearLayout)convertView.findViewById(R.id.ll_firstcolumn);
                viewHolder.ll_datagroup=(LinearLayout)convertView.findViewById(R.id.ll_datagroup);
                viewHolder.rowClickListener=new RowClickListener();
                convertView.setTag(viewHolder);
            }else {
                viewHolder= (ViewHolder) convertView.getTag();
            }
            //更新每行的views的数据
            updateViews(conentAdapter,viewHolder,viewHolder.ll_firstcolumn,viewHolder.ll_datagroup,position);
            //更熟的views数据后重新测量高度,取那一行的最大高度作为整行的高度
            maxHeight=getMaxHeight(conentAdapter,viewHolder.views);
            //重新更新view到表格上
            updateUI(conentAdapter,viewHolder.ll_firstcolumn,viewHolder.ll_datagroup,viewHolder.views,maxHeight);

            //为了尽可能少的影响ScrollView的触摸事件,所以点击事件这里取个巧,直接设置在这两个Linearlayout上
            viewHolder.rowClickListener.setData(conentAdapter,position,convertView);
            viewHolder.ll_firstcolumn.setOnClickListener(viewHolder.rowClickListener);
            viewHolder.ll_datagroup.setOnClickListener(viewHolder.rowClickListener);
            return convertView;
        }


    }


    private ViewHolder updateViews(VHBaseAdapter conentAdapter, ViewHolder viewHolder,LinearLayout ll_firstcolumn, LinearLayout ll_datagroup,int row) {
        for(int i=0;i<conentAdapter.getContentColumn();i++) {

            if(!firstColumnIsMove&&i==0){
                View view= conentAdapter.getTableCellView(row, 0, viewHolder.views[0], ll_firstcolumn);
                viewHolder.views[0]=view;
            }else {
                View view=conentAdapter.getTableCellView(row, i, viewHolder.views[i], ll_datagroup);
                viewHolder.views[i]=view;
            }
        }
        return viewHolder;
    }

    private int getMaxHeight(VHBaseAdapter conentAdapter,View[] views) {
        int maxHeight=0;
        for(int i=0;i<conentAdapter.getContentColumn();i++) {
                //测量模式:宽度以标题行各列的宽度为准,高度为自适应
                int w = View.MeasureSpec.makeMeasureSpec(widthMap.get(""+i), MeasureSpec.EXACTLY);
                int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
                views[i].measure(w,h);
                maxHeight = Math.max(maxHeight, views[i].getMeasuredHeight());
        }
        return maxHeight;
    }

    private void updateUI(VHBaseAdapter conentAdapter,  LinearLayout ll_firstcolumn, LinearLayout ll_datagroup,View[] views,int maxHeight) {
        //其实这里可以优化一下,不用remove掉全部又加一次,以后再优化一下。。。。
        ll_firstcolumn.removeAllViews();
        ll_datagroup.removeAllViews();
        for(int i=0;i<conentAdapter.getContentColumn();i++) {

            if(!firstColumnIsMove&&i==0){
                ll_firstcolumn.addView(views[0],widthMap.get("0"),maxHeight);
            }else {
                ll_datagroup.addView(views[i],widthMap.get(""+i),maxHeight);
            }
        }

    }

    public class RowClickListener implements OnClickListener {

        private VHBaseAdapter conentAdapter;
        private int row;
        private View convertView;
        public void setData(VHBaseAdapter conentAdapter, int row, View convertView){
            this.conentAdapter=conentAdapter;
            this.row=row;
            this.convertView=convertView;
        }
        @Override
        public void onClick(View v) {
            if(null!=conentAdapter&&null!=convertView){
                conentAdapter.OnClickContentRowItem(row,convertView);
            }
        }
    }

public class ViewHolder {
    LinearLayout  ll_firstcolumn;
    LinearLayout ll_datagroup;
    View[] views;
    RowClickListener rowClickListener;
}



}
这里用到的布局文件vhtable_item_listview如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/row_hlistview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <LinearLayout
        android:id="@+id/ll_firstcolumn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        >

    </LinearLayout>
    <com.demo.zj.vhtableview.HListViewScrollView
        android:id="@+id/chs_datagroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="false"
        android:scrollbars="none"
       >

        <LinearLayout
            android:id="@+id/ll_datagroup"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:orientation="horizontal">
        </LinearLayout>
    </com.demo.zj.vhtableview.HListViewScrollView>

</LinearLayout>
稍作修改的HorizontalScrollView如下



import android.content.Context;
import android.support.v4.view.ViewConfigurationCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.HorizontalScrollView;

public class HListViewScrollView extends HorizontalScrollView {


	public HListViewScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	
	public HListViewScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public HListViewScrollView(Context context) {
		super(context);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		//记录当前触摸的HListViewScrollView
		if(null!=this.listener){
			listener.setCurrentTouchView(this);
		}
		return super.onTouchEvent(ev);
	}
	
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		//当当前的HListViewScrollView被触摸时,滑动其它
		if(null!=this.listener&&null!=listener.getCurrentTouchView()&&listener.getCurrentTouchView() == this) {
			listener.onUIScrollChanged(l, t, oldl, oldt);
		}else{
			super.onScrollChanged(l, t, oldl, oldt);
		}
	}

	private ScrollChangedListener listener;
	public void setScrollChangedListener(ScrollChangedListener listener){
		this.listener=listener;
	}

	public interface ScrollChangedListener{

		public void setCurrentTouchView(HListViewScrollView currentTouchView);

		public HListViewScrollView getCurrentTouchView();
		public void onUIScrollChanged(int l, int t, int oldl, int oldt);
	}
}

里面的注释其实说的挺清楚了,这里说一下大概的思路,说白了就是一个LinearLayout,里面添加了两个子view,一个标题行,一个listview,标题行和listview的item用的都是同一个布局,这个布局里面也是一个LinearLayout横向包含两个子view,一个普通的LinearLayout和一个HListViewScrollView,当设置第一列不可移动的时候,就把第一列放到那个普通的LinearLayout里,不然就全扔到HListViewScrollView里。

然后就把标题行里跟listview里面所有创建了的HListViewScrollView都放一个List里面,然后监控各个HListViewScrollView的横向滑动事件,某一个滑动的时候,其他的也跟着滑动。

在加入标题行的view的时候,就进行控件的测量,并把宽度记下来,然后下面listview里面的每一列就都跟标题行一致,高度则全都是自适应。

其实东西不多,就这些东西,稍微封装优化了一下。。。。。


源码Demo:

https://git.oschina.net/jiancode/VHTable.git

拼多多Android面试题及参考答案 Android 系统采用分层架构设计,从底层到上层依次为Linux 内核层硬件抽象层(HAL)系统运行时库层应用框架层应用层,共五层。位置:Linux 内核层与系统运行时库层之间,是“硬件与系统的隔离层”。核心作用:屏蔽硬件差异,为上层提供统一的硬件访问接口,解决 Android 开源与硬件厂商闭源的矛盾,具体功能如下:硬件能力抽象:将硬件的具体实现(如不同厂商的摄像头芯片、音频芯片)封装为标准化接口(如Camera HALAudio HAL。 阅读详情

相关推荐

Android app 自定义可横竖滑动的RecyclerView(一)

在app开发中,有时候竖屏的时候 在绘制一张表格的时候,而表格列数行数都比较多的时候,这时候就需要 支持列表横竖屏都能滑动才行 所以就需要自定义RecyclerView 支持横竖滑动 1.提供适配器 接口 给自定义横竖滑动 适配器调用 import android.view.ViewGroup; import androidx.recyclerview.widget.RecyclerView; public abstract class PanelAdapter { public abst

安卓兼职framework和app工程师的博客 1320

android 横向滚动 tableview,Android自定义表格 LockTableView

LockTableView自定义表格,可锁定双向表头,自适应列宽,自适应行高,下拉刷新,上拉加载,快速集成效果展示工程集成说明第一步//在工程gradle文件里allprojects {repositories {.......maven { url 'https://jitpack.io' }......}}//如果不在工程gradle文件里加入,也可以加入模块gradle文件中reposito...

weixin_34207787的博客 1093

Android双方向滚动列表实现——头部与侧边栏固定双向滑动效果实战

✅ 完全掌控事件分发;✅ 易添加遮罩、阴影等特效;❌ 代价高昂:手势冲突仍需精细处理;丧失内置优化(预加载、预测布局);布局计算繁琐,易出 bug;维护成本高。更适合做高度定制化的复合控件,而非通用解决方案。当你面对一个复杂的二维数据展示需求时,与其在ScrollView嵌套地狱中挣扎,不如一次性投资构建一个基于的双向滚动引擎。它的优势不止于“能用”,而是:- ✅ 架构清晰,易于维护;- ✅ 性能卓越,内存友好;

weixin_42465332的博客 1170

借助HorizontalScrollView实现多列ListView的横向滑动(含动态加载)

在Android中使用ListVIew显示多列数据表时会遇到屏幕宽度不够, 无法完全显示的问题, 以下的例子是我结合网上的各种方案总结的一种较好的解. 自定义Adapter:  public class HolderAdapter extends BaseAdapter { private static final String TAG = "HolderAdapter";

牟蘑菇的专栏 8179

Android报表表格实现:行头列头与双向滚动

创建自定义表格控件的第一步是继承并扩展现有的View类,实现onDraw方法来绘制表格行和列。通过使用Canvas类,开发者可以绘制直线来形成网格,并在网格交点处绘制数据。// 构造方法、onMeasure、onDraw方法省略@Override// 绘制网格线row++) {col++) {// 绘制数据// ...除了基础的绘制功能,还需要为自定义表格控件定义属性和方法,以便开发者能够设置行高、列宽和样式等。这些可以通过定义XML属性并在onMeasure。

weixin_32099703的博客 813

Android双向表格可滑动可双向适配

本人根据一个网上的Demo改的,增加功能:设置表头,横向适配

Android 自定义表格(第一行及第一列固定,其他列可滑动)

结合HorizontalScrollView和RecyclerView,自定义可滑动表格

mojo001的博客 4575

Android 自定义可上下左右滑动table

这是一款可以上下左右滑动的android控件,和前端的table tr、td、差不多,全部源码,可以自己重新定义

android中双向滑动listview

因项目中需要实现表格类的显示方式,显示数量不确定,同时产品对一些体验,以及设计的要求,参考网上资料,自己写的一个双向滑动listview,废话不多说直接上代码和效果图 1.效果图 2代码: 首先,界面说明(其他东西可忽略项目中需要使用),竖向是一个listview,横向是一个自定义HorizontalScrollView,(此处没有使用自定义横向listview,因为时间紧,

lisx_wuguiconghua的博客 1719

图像配准方法之灰度信息法

这系列文章是5年前的,也是从自己的QQ(632846506)日志中移过来的。https://user.qzone.qq.com/632846506/infocenter。      图像配准的方法主要有三种:基于灰度信息方法;基于空间变换域方法;基于图像特征的方法。 一、灰度信息法。     灰度信息法直接利用两幅图像之间灰度度量的相似性,以图像内部的信息为依据,采用搜索方法寻找相似度最大或

月秀明竹的专栏 1万+

航空发动机轴承故障诊断

《航空发动机主轴承故障诊断的挑战与HIT数据集研究》 摘要: 航空发动机主轴承作为关键部件,其可靠性直接影响飞行安全。然而,主轴承故障诊断面临信号信噪比低、传输路径复杂、故障类型多样、变工况运行等挑战。哈尔滨工业大学团队开发的HIT数据集为研究提供了真实工况下的实验数据,包含正常、内圈和外圈故障三种状态,具有高仿真度和强挑战性特点。研究表明,传统诊断方法在该数据集上准确率仅71-85%,突显了诊断难度。团队提出的ISONet新方法通过输入空间过参数化技术,将诊断准确率提升至99%以上,为航空发动机轴承故障诊

tyutwuxuan的博客 994

Recyclerview部分列固定部分列滑动学习备忘

【Android】RecyclerView实现表格上下左右、横向纵向双向滑动效果_android recyclerview横竖向-优快云博客。RecyclerView之实现部分字段固定,其余部分可左滑的效果_安卓中使用recycleview某列固定左侧不动-优快云博客。android股票联动_第一列固定其他列可左右上下滑动_android 第一列不动,其他滚动-优快云博客。

sdaujz的博客 694

遥感图像语义分割的全流程实现(Python代码)

本节介绍了加载遥感 RGB 图像和对应的单通道掩膜(mask)。掩膜中每个像素值为类别索引(如0=背景,1=植被,2=建筑),通过 transform 统一缩放(256×256)和归一化(ImageNet 均值/标准差),确保输入模型的一致性。# 自定义数据集类(适配遥感RGB+单通道掩膜)mask = Image.open(mask_path).convert("L") # 单通道掩膜return image, mask.squeeze(0).long() # 返回RGB图像和类别索引。

qq_42679807的博客 1851

Android中ListView结合HorizontalScrollView实现水平和竖直方向上的滚动效果

    一言不合先上图:     本文实现上图效果采用了两种方案:     方案一:采用头布局+左右两个ListView实现,头布局的右半部分以及右边的ListView完全包含在自定义HorizontalScrollView中。     首先自定义一个CusHorizontalScrollView,在其中声明另一个HorizontalScrollView mView,添加set方法,复写...

tianyaluqingchen的博客 2547

MoveIt2项目想换掉KDL求解器?试试这个trac_ik插件(附源码编译避坑指南)

本文详细介绍了如何在MoveIt2项目中用trac_ik插件替代KDL求解器,提升机械臂运动学求解的效率和成功率。内容涵盖环境准备、源码编译避坑、项目集成及性能调优,特别适合需要高精度控制的协作机械臂应用场景。通过实测数据对比,trac_ik在求解时间和奇异点处理上显著优于传统KDL求解器。

weixin_30730053的博客 692

STM32F407实现LwIP的MQTT客户端并连接到服务器

这个是用LwIP协议栈中自带的MQTT客户端API写成的,代码注释很详细,附带有服务端的展示。LwIP版本是2.1.2.

wait_for_STM32的博客 6394

【Android】RecyclerView实现表格上下左右、横向纵向双向滑动效果

Android屏幕显示范围有限,在数据可视化需求中经常要使用这样的表格:横向纵向都能滑动,左侧栏目固定,右边可以整体上下左右滑动。例如股票、证券、课程表、值日表、Excel等等 主要就是分为 标题 和 内容 两部分,其中内容部分一般都是嵌套RecyclerView,使得标题和内容左右横向滑动时是一起滑动的,且不能错位。

full courage的博客 5208

第五章 TTM 后备管理:5.6系统内存域

系统内存域由 TTM 内置资源管理器管理,通过 ttm_tt 承载页信息,依赖 ttm_pool 提供物理页。ttm_tt 管理页数组、缓存属性与状态标志,支持外部页与换出机制。初始化分 ttm_tt_init 与 ttm_sg_tt_init,生命周期包括创建、填充、释放与销毁。页池针对 write-combined、uncached 及一致性 DMA 分配的页进行缓存,提升性能并减少 TLB 刷新。分配时高阶优先、批量设置缓存属性,回收时清零后归还池中,确保高效复用。

图形/计算GPU的驱动与虚拟化技术分享园地 2560

无限数据的双向虚拟滚动

很多关于虚拟滚动的文章,我发现都是基于固定庞大数据量提前计算好可滚动的高度向下滚动的虚拟滚动,

chenjixue的博客 617

Yolov8轻量级网络:Ghostnet、G_ghost、Ghostnetv2家族大作战(一):华为Ghostnet,超越谷歌MobileNet | CVPR2020

Yolov8引入轻量级网络Ghostnet、G_ghost、Ghostnetv2等,减少最新的深度神经网络的计算成本,引入高效的神经网络结构。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 2565

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Android 横向滚动列表 (类似横向ListView)

Android 横置列表

qq_19688207的博客 4811

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Android RecycleView实现横向,纵向都可滑动的列表

问题 1.RecycleView默认是纵向滑动的,可以通过setOrientation(LinearLayoutManager.HORIZONTAL)设置为横向滑动。 //指定列表布局方式,默认是纵向垂直 recycleView.setLayoutManager(new LinearLayoutManager(this)); //指定列表线性布局,横向水平...

DeMonnnnnn 1万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Android实现Excel表格,且表格能左右、上下滑动

1、自定义实现一个水平滚动控件HorizontalScrollView import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.HorizontalScrollView; /** * Created by ...

weixin_34284188的博客 721

Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效

转载请注明出处:http://blog.youkuaiyun.com/guolin_blog/article/details/9671609 记得在很早之前,我写了一篇关于Android滑动菜单的文章,其中有一个朋友在评论中留言,希望我可以帮他将这个滑动菜单改成双向滑动的方式。当时也没想花太多时间,简单修改了一下就发给了他,结果没想到后来却有一大批的朋友都来问我要这份双向滑动菜单的代码。由于这份代码写得很不...

移动编程 373
下一篇: android stduio多项目依赖的git版本控制+jenkins自动构建
jian_code
博客等级 码龄10年 4粉丝 2原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值