HorizontalScrollView下自定义ViewGroup无法实现滑动

本文介绍了在Android中自定义ViewGroup MyViewGroup时遇到的滑动问题,该问题发生在HorizontalScrollView内。文章通过代码展示了解决方案,包括自定义ViewGroup的onMeasure和onLayout方法,以及添加滚动监听接口ScrollListenerInfer,以实现滑动时的布局更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


代码:自定义MyViewGroup类


import android.content.Context;
import android.view.View;
import android.view.ViewGroup;


public class MyViewGroup extends ViewGroup {


private final static int VIEW_MARGIN = 100;


private int lengthX;
private int lengthY;


private ScrollListenerInfer listener;


public MyViewGroup(Context context) {
super(context);
}


public void onListener(ScrollListenerInfer l) {
this.listener = l;
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
for (int index = 0; index < getChildCount(); index++) {
final View child = getChildAt(index);
/**
* measure MeasureSpec.EXACTLY:精确的尺寸 MeasureSpec.AT_MOST:最大可获得的空间
* MeasureSpec.UNSPECIFIED:对于控件尺寸来说,没有任何参考意义
*/
child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}


@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
// int row = 0;// 行数
int line = 0;// 列数
lengthX = left;
lengthY = top;
for (int i = 0; i < getChildCount(); i++) {
final View child = this.getChildAt(i);
int width = child.getMeasuredWidth();
int height = child.getMeasuredHeight();

/**
* 自动换列
*/
lengthX = line * (width + VIEW_MARGIN) + VIEW_MARGIN + width + left;
lengthY += height + VIEW_MARGIN;
if (lengthY > bottom) {
line++;
lengthX = line * (width + VIEW_MARGIN) + VIEW_MARGIN + width
+ left;
lengthY = height + VIEW_MARGIN + top;
}

/**
* 自动换行
*/
// lengthX += width + VIEW_MARGIN;
// lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height + top;
// if (lengthX > right) {
// lengthX = width + VIEW_MARGIN + left;
// row++;
// lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height
// + bottom;
// }

child.layout(lengthX - width, lengthY - height, lengthX, lengthY);// 子控件的总宽度、高度
}
listener.onLoad(lengthX);
}


}

代码:MeetingListActivity

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;


import zdaap.meeting.pad.beans.MeetingBean;
import zdaap.meeting.pad.json.GetNetWorkData;
import zdaap.meeting.pad.util.NetWorkUtil;
import zdaap.meeting.pad.view.MyViewGroup;
import zdaap.meeting.pad.view.ScrollListenerInfer;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextPaint;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;


@SuppressLint("HandlerLeak")
public class MeetingListActivity extends BaseActivity {


private Calendar c;// 日期控件


private LinearLayout home_middle_layout;

private List<MeetingBean> meeting;
private ArrayList<String> meetingInfo;

private EditText password;
private Dialog d;// 密码对话框

@SuppressWarnings("unchecked")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.meeting_list_layout);

home_middle_layout = (LinearLayout)findViewById(R.id.home_middle_layout);

findViewById(R.id.home_title_close).setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
doExit();
}
});


findViewById(R.id.home_title_date).setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
initDate();
}
});

List<MeetingBean> data = (List<MeetingBean>) getLastNonConfigurationInstance();
if (data != null) {
meeting = data;
initUI();
} else {
if (true == NetWorkUtil.isNetWork(this)) {
SimpleDateFormat temp = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String date = temp.format(new Date());
getNetData(date);
} else {
Toast.makeText(this, "没有连接网络", Toast.LENGTH_SHORT).show();
}
}


}

/**
* 初始化UI
*/
private void initUI(){

final MyViewGroup home_meeting_item = new MyViewGroup(this);
home_meeting_item.onListener(new ScrollListenerInfer() {
@Override
public void onLoad(int width) {
ViewGroup.LayoutParams params = home_meeting_item.getLayoutParams();
params.width = width;
home_meeting_item.setLayoutParams(params);
}
});

for (int i = 0; i < meeting.size(); i++) {

/**
* 根
*/
RelativeLayout meeting_item_layout = new RelativeLayout(this);
RelativeLayout.LayoutParams layoutParamsRoot = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
meeting_item_layout.setLayoutParams(layoutParamsRoot);
meeting_item_layout.setBackgroundResource(R.drawable.home_middle_item_bg);

ArrayList<String> info = new ArrayList<String>();
info.add(meeting.get(i).ID);
info.add(meeting.get(i).MEETING_TIME);
info.add(meeting.get(i).PASSWORD);
info.add(meeting.get(i).flag + "");
info.add(i + "");

meeting_item_layout.setTag(info);
meeting_item_layout.setOnClickListener(new OnClickListener() {
@SuppressWarnings("unchecked")
@Override
public void onClick(View v) {
RelativeLayout r = (RelativeLayout)v;
meetingInfo = (ArrayList<String>)r.getTag(); 

if(meeting.get(Integer.parseInt(meetingInfo.get(4).toString())).getFlag() == 2){
Intent intent = new Intent(MeetingListActivity.this, MeetingFilesActivity.class);
Bundle bundle = new Bundle();
bundle.putStringArrayList("meetingInfo", meetingInfo);
intent.putExtras(bundle);
startActivity(intent);
}else{
passwordDialog();
}

}
});

/**
* 会议室
*/
TextView meeting_item_where = new TextView(this);
RelativeLayout.LayoutParams paramsWhere = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, 
RelativeLayout.LayoutParams.WRAP_CONTENT);
paramsWhere.addRule(RelativeLayout.CENTER_HORIZONTAL);
paramsWhere.setMargins(0, 20, 0, 20);
meeting_item_where.setLayoutParams(paramsWhere);
meeting_item_where.setText(meeting.get(i).ROOM);
meeting_item_where.setTextSize(20);
meeting_item_where.setTextColor(Color.WHITE);
// 加粗
TextPaint tp = meeting_item_where.getPaint();
tp.setFakeBoldText(true);
meeting_item_layout.addView(meeting_item_where);

/**
* 会议标题、时间、会期等布局
*/
LinearLayout meeting_contant_layout = new LinearLayout(this);
RelativeLayout.LayoutParams layoutParamsCant = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParamsCant.addRule(RelativeLayout.CENTER_VERTICAL);
layoutParamsCant.setMargins(15, 0, 0, 0);
meeting_contant_layout.setLayoutParams(layoutParamsCant);
meeting_contant_layout.setOrientation(LinearLayout.VERTICAL);

/**
* 标题
*/
TextView meeting_contant_title = new TextView(this);
LinearLayout.LayoutParams paramsTitle = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, 
LinearLayout.LayoutParams.WRAP_CONTENT);
paramsTitle.setMargins(0, 20, 0, 0);
meeting_contant_title.setLayoutParams(paramsTitle);
meeting_contant_title.setText(meeting.get(i).TITLE);
meeting_contant_title.setTextSize(15);
meeting_contant_title.setTextColor(getResources().getColor(R.color.black_gray));
meeting_contant_layout.addView(meeting_contant_title);

/**
* 线
*/
ImageView meeting_contant_line = new ImageView(this);
LinearLayout.LayoutParams paramsLine = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, 
LinearLayout.LayoutParams.WRAP_CONTENT);
paramsLine.setMargins(0, 15, 0, 10);
meeting_contant_line.setLayoutParams(paramsLine);
meeting_contant_line.setImageResource(R.drawable.home_middle_line);
meeting_contant_layout.addView(meeting_contant_line);

/**
* 会议时间Tab
*/
TableRow contant_tab_date = new TableRow(this);
LinearLayout.LayoutParams paramsDate = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, 
LinearLayout.LayoutParams.WRAP_CONTENT);
paramsDate.setMargins(10, 0, 0, 0);
contant_tab_date.setLayoutParams(paramsDate);
contant_tab_date.setOrientation(LinearLayout.HORIZONTAL);

TextView td = new TextView(this);
td.setText("会议时间:");
td.setTextColor(Color.RED);
contant_tab_date.addView(td);

/**
* 时间
*/
TextView meeting_contant_date = new TextView(this);
meeting_contant_date.setText(meeting.get(i).MEETING_TIME);
contant_tab_date.addView(meeting_contant_date);
meeting_contant_layout.addView(contant_tab_date);

/**
* 会期Tab
*/
TableRow contant_tab_time = new TableRow(this);
LinearLayout.LayoutParams paramsTime = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, 
LinearLayout.LayoutParams.WRAP_CONTENT);
paramsTime.setMargins(10, 0, 0, 0);
contant_tab_time.setLayoutParams(paramsTime);
contant_tab_time.setOrientation(LinearLayout.HORIZONTAL);

TextView tt = new TextView(this);
tt.setText("会  期:");
tt.setTextColor(Color.RED);
contant_tab_time.addView(tt);

/**
* 会期
*/
TextView meeting_contant_time = new TextView(this);
meeting_contant_time.setText(meeting.get(i).DURATION);
contant_tab_time.addView(meeting_contant_time);
meeting_contant_layout.addView(contant_tab_time);

/**
* 申请部门Tab
*/
TableRow contant_tab_where = new TableRow(this);
LinearLayout.LayoutParams paramshere = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, 
LinearLayout.LayoutParams.WRAP_CONTENT);
paramshere.setMargins(10, 0, 0, 0);
contant_tab_where.setLayoutParams(paramshere);
contant_tab_where.setOrientation(LinearLayout.HORIZONTAL);

TextView tw = new TextView(this);
tw.setText("申请部门:");
tw.setTextColor(Color.RED);
contant_tab_where.addView(tw);

/**
* 申请部门
*/
TextView meeting_contant_where = new TextView(this);
meeting_contant_where.setText(meeting.get(i).APPLY_DEPT);
contant_tab_where.addView(meeting_contant_where);
meeting_contant_layout.addView(contant_tab_where);

meeting_item_layout.invalidate();
meeting_item_layout.addView(meeting_contant_layout);

home_meeting_item.invalidate();// 更新
home_meeting_item.addView(meeting_item_layout);

}

home_middle_layout.addView(home_meeting_item);

}

/**
* 密码对话框
*/
private void passwordDialog(){
d = new Dialog(this, R.style.myDialogTheme);
d.show();
d.setCanceledOnTouchOutside(true);// 点击对话框外部取消对话框显示
Window window = d.getWindow();
window.setContentView(R.layout.home_dialog_layout);
password = (EditText)window.findViewById(R.id.home_dialog_pass);
window.findViewById(R.id.home_dialog_ok).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(password.getText() != null && !password.getText().toString().equals("")){
closeInputWindow();
inientView();
}else{
Toast.makeText(MeetingListActivity.this, "密码不能为空", Toast.LENGTH_SHORT).show();
}
}
});
}

/**
* 关闭软键盘
*/
private void closeInputWindow() {
if(password != null){
InputMethodManager imm = (InputMethodManager) getSystemService(MeetingFilesActivity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(password.getWindowToken(), 0);
}
}

/**
* 跳转
*/
private void inientView(){
if (meetingInfo.get(2).toString().equals(password.getText().toString().trim())){
if (d != null) {
d.hide();
d = null;
}

int i = Integer.parseInt(meetingInfo.get(3).toString());
i++;
meeting.get(Integer.parseInt(meetingInfo.get(4).toString())).setFlag(i);

Intent intent = new Intent(this, MeetingFilesActivity.class);
Bundle bundle = new Bundle();
bundle.putStringArrayList("meetingInfo", meetingInfo);
intent.putExtras(bundle);
startActivity(intent);
} else {
Toast.makeText(this, "密码错误", Toast.LENGTH_SHORT).show();
}
}

/**
* 发送通知
*/
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:
initUI();
break;
}
};
};

/**
* 获取网络数据
*/
private void getNetData(final String date){
new Thread(new Runnable() {
@Override
public void run() {

showWaitingDialog();

String s = date;
List<MeetingBean> result = GetNetWorkData.getMeetingList(s);
if (result != null && result.size() > 0) {
meeting = result;
handler.sendEmptyMessage(1);
} else {
// Toast.makeText(MeetingListActivity.this, "暂无记录", Toast.LENGTH_SHORT).show();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MeetingListActivity.this, "暂无记录", Toast.LENGTH_SHORT).show();
}
});
}

hideWaitingDialog();

}
}).start();
}


/**
* 实例化日期
*/
private void initDate() {
c = Calendar.getInstance();
Dialog dialog = new DatePickerDialog(this,
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, monthOfYear);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
getNewDate();
}
}, c.get(Calendar.YEAR), c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH));
dialog.show();
}


/**
* 获取选择后的日期
*/
private void getNewDate() {
SimpleDateFormat temp = new SimpleDateFormat("yyyy-MM-dd",
Locale.getDefault());
String s = temp.format(c.getTime());
home_middle_layout.removeAllViews();
// home_middle_layout.invalidate();
getNetData(s);
}


/**
* 退出程序
*/
private void doExit() {
AlertDialog.Builder ab = new AlertDialog.Builder(this);
ab.setTitle("提示");
ab.setMessage("确定要退出吗");
ab.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
if(waitingDialog != null){
waitingDialog.hide();
waitingDialog = null;
}
MeetingListActivity.this.finish();
}
});
ab.setNegativeButton("取消", null);
ab.create();
ab.show();
}

/**
* 切换屏幕回调函数,用户保存数据
*/
@Override
public Object onRetainNonConfigurationInstance() {
List<MeetingBean> data = meeting;
return data;
}


@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
doExit();
}
return super.onKeyDown(keyCode, event);
}

}

代码:meeting_list_layout   XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ebebeb"
    android:orientation="vertical" >


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


        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="20sp"
            android:background="@drawable/meeting_logo"
            android:contentDescription="@string/sss" />


        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="20sp"
            android:gravity="center_vertical"
            android:orientation="horizontal" >


            <ImageView
                android:id="@+id/home_title_date"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="50dp"
                android:background="@drawable/home_title_date_bg"
                android:contentDescription="@string/sss" />


            <ImageView
                android:id="@+id/home_title_close"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/meeting_title_close_bg"
                android:contentDescription="@string/sss" />
        </LinearLayout>
    </RelativeLayout>
    
    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        android:fadingEdge="none"
        android:scrollbars="none" >


        <LinearLayout
            android:id="@+id/home_middle_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#ebebeb"
            android:orientation="horizontal" >
        </LinearLayout>
    </HorizontalScrollView>
 

</LinearLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值