【问题标题】:Android Listview autoscroll makes items invisibleAndroid Listview 自动滚动使项目不可见
【发布时间】:2020-10-15 11:23:30
【问题描述】:

我有进度项目的进度列表视图。每当项目完成时,我都会勾选它。

此进度项目分为阶段。每个阶段都可以包含步骤。完成所有步骤并用复选标记标记后,代码将整个阶段标记为完成。

最后,我所做的只是渲染阶段的列表视图,并且对于每个阶段,我会在其中动态添加另一个列表视图。我最终得到了包含更多列表视图的列表视图。

这很好用,我没有任何问题。

我的老板让我创建自动滚动器,它会按照已完成的步骤进行。这是我实现的,很高兴看到它有效。

问题:我很高兴它只在达到一半多一点的时候才起作用。然后突然物品消失了。当我触摸列表时,列表会返回顶部并且所有项目都可见。

知道什么会导致这种行为吗?

这方面的代码很大,所以我只分享我认为需要的部分。

//适配器

public class ProcessFeedbackAdapter extends android.widget.BaseAdapter {

    public static final String TAG = "ProcessFeedbackAdapter";
    public Context appContext;
    public ProgressOverviewData ProgressOverviewData;
    public ListView Listview;
    public int FirstNotCompletedIndex=0;



    public void UpdateList(){

        HotApplication.getHandler().post(new Runnable(){
            @Override
            public void run() {
                notifyDataSetChanged();
            }
        });

    }

    public ProcessFeedbackAdapter(Context Context,ProgressOverviewData ProgressOverviewData,ListView listview){
        this.appContext=Context;
        this.ProgressOverviewData=ProgressOverviewData;
        this.Listview=listview;
    }
    @Override
    public int getCount() {
        return ProgressOverviewData.Phases.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

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

    public void ScrollToCurrentlyActiveTask(int y){

        int listviewBottom = Listview.getBottom();
        if(listviewBottom <y*50){

            Listview.scrollTo(0, listviewBottom);
        }
        else {
            Listview.scrollTo(0,y*50);
        }
        Listview.computeScroll();
    }


    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        try {

            Phase curItem = ProgressOverviewData.Phases.get(i);
            LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.progress_list_item, null);
            ListView ChildList=view.findViewById(R.id.childrenList);
            ViewGroup.LayoutParams params = ChildList.getLayoutParams();
            int ListHeight=curItem.PhaseSteps.size()*50;
            params.height=ListHeight;
            ChildList.setLayoutParams(params);

            TextView ProgressMessage = (TextView) view.findViewById(R.id.ProgressMessage);
            ImageView Check = (ImageView) view.findViewById(R.id.CheckMark);
            ImageView ErrorMark = (ImageView) view.findViewById(R.id.ErrorMark);

            ProcessFeedbackChildrenAdapter ChilAdapter=new ProcessFeedbackChildrenAdapter(appContext,curItem.PhaseSteps);
            ChildList.setAdapter(ChilAdapter);

            int CheckVisibility = 0;
            int ErrorVisibility=0;
            if(curItem.Status.equals(AppEnums.StepResult.NotCompleted)){
                CheckVisibility=View.INVISIBLE;
                ErrorVisibility=View.INVISIBLE;
            }
            else if(curItem.Status.equals(AppEnums.StepResult.Completed)){
                    CheckVisibility=View.VISIBLE;
                    ErrorVisibility=View.INVISIBLE;
            }
            else if(curItem.Status.equals(AppEnums.StepResult.Failed)){
                ErrorVisibility=View.VISIBLE;
                CheckVisibility=View.INVISIBLE;
            }

            Check.setVisibility(CheckVisibility);
            ErrorMark.setVisibility(ErrorVisibility);
            ProgressMessage.setText(curItem.PhaseName);


            return view;
        } catch (Exception e) {
            System.out.println("Something went wrong.");
        }
        return view;
    }
}

class ProcessFeedbackChildrenAdapter extends android.widget.BaseAdapter {

    public static final String TAG = "ProcessFeedbackChildrenAdapter";
    public Context appContext;
    public ArrayList<Step> Steps= new ArrayList<Step>();



    public void UpdateList(){

        HotApplication.getHandler().post(new Runnable(){
            @Override
            public void run() {
                notifyDataSetChanged();
            }
        });

    }

    public ProcessFeedbackChildrenAdapter(Context Context,ArrayList<Step> Steps){
        this.appContext=Context;
        this.Steps=Steps;
    }
    @Override
    public int getCount() {
        return Steps.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

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



    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        try {

            LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.progress_list_item_children, null);


            TextView ProgressMessage = (TextView) view.findViewById(R.id.ProgressMessage);
            ImageView Check = (ImageView) view.findViewById(R.id.CheckMark);
            ImageView ErrorMark = (ImageView) view.findViewById(R.id.ErrorMark);
            Step curItem = Steps.get(i);


            int CheckVisibility = 0;
            int ErrorVisibility=0;
            if(curItem.Status== AppEnums.StepResult.NotCompleted){
                CheckVisibility=View.INVISIBLE;
                ErrorVisibility=View.INVISIBLE;
            }else {
                if(curItem.Status== AppEnums.StepResult.Completed){
                    CheckVisibility=View.VISIBLE;
                    ErrorVisibility=View.INVISIBLE;
                }
                else if(curItem.Status==AppEnums.StepResult.Failed){
                    ErrorVisibility=View.VISIBLE;
                    CheckVisibility=View.INVISIBLE;
                }
            }



            ProgressMessage.setText(curItem.StepName);

            Check.setVisibility(CheckVisibility);
            ErrorMark.setVisibility(ErrorVisibility);

            return view;
        } catch (Exception e) {
            System.out.println("Something went wrong.");
        }
        return view;
    }
}

// 主列表视图

        <ListView
            android:id="@+id/ProgressStepsContainer"
            android:layout_width="0dp"
            android:layout_height="267dp"
            android:fastScrollEnabled="false"
            android:scrollbarThumbVertical="@drawable/scrollbar_vertical_thumb"
            android:verticalScrollbarPosition="left"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/ProgressErrorContainer"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/ProgressMessage">

        </ListView>

// 阶段列表项

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="0dp">

    <ImageView
        android:id="@+id/CheckMark"
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_overview_check" />

    <ImageView
        android:id="@+id/ErrorMark"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:visibility="visible"
        app:layout_constraintStart_toStartOf="@+id/CheckMark"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_overview_error" />

    <TextView
        android:id="@+id/ProgressMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="TextView"
        android:textAlignment="center"
        android:textColor="@color/colorWhitish"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/CheckMark"
        app:layout_constraintStart_toEndOf="@+id/CheckMark"
        app:layout_constraintTop_toTopOf="parent" />

    <ListView
        android:id="@+id/childrenList"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintStart_toEndOf="@+id/CheckMark"
        app:layout_constraintTop_toBottomOf="@+id/ProgressMessage" />

</androidx.constraintlayout.widget.ConstraintLayout>

// 步骤(内部)列表项

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="50dp">

    <ImageView
        android:id="@+id/CheckMark"
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_overview_check" />

    <ImageView
        android:id="@+id/ErrorMark"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:visibility="visible"
        app:layout_constraintStart_toStartOf="@+id/CheckMark"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_overview_error" />

    <TextView
        android:id="@+id/ProgressMessage"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="TextView"
        android:textAlignment="center"
        android:textColor="@color/colorWhitish"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/CheckMark"
        app:layout_constraintStart_toEndOf="@+id/CheckMark"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

【问题讨论】:

    标签: java android listview


    【解决方案1】:

    您的适配器代码在我的手机中无效。仅显示部分子列表。另外,我认为ExpandableListView更容易实现您的要求。因此,我按照您的数据结构创建了以下使用 ExpandableListView 的演示代码。您可以开始一个新项目并尝试一下。

    MainActivity.java:

    public class MainActivity extends AppCompatActivity {
    ProgressOverviewData sampleData;
    ProcessFeedbackAdapter1 adapter;
    ExpandableListView listView;
    TextView textView;
    int completedPhase = 0;
    
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        sampleData = new ProgressOverviewData("Project", new ArrayList<Phase>());
        textView = findViewById(R.id.ProgressMessage);
        textView.setText(sampleData.projectName);
    
        listView = findViewById(R.id.ProgressStepsContainer);
        adapter = new ProcessFeedbackAdapter1(this, sampleData);
        listView.setAdapter(adapter);
        // Disable ExpandableListView from group collapse by override OnGroupClickListener.
        listView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView expandableListView, View view, int i, long l) {
                return true;
            }
        });
        for (int i = 0; i < sampleData.Phases.size(); i++) listView.expandGroup(i);
    
        Button btAddPhase = findViewById(R.id.bt_add_phase);
        btAddPhase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Phase newPhase = genNewPhase();
                sampleData.Phases.add(newPhase);
                adapter.notifyDataSetChanged();
                listView.expandGroup(sampleData.Phases.size() - 1);
                textView.setText(sampleData.projectName + " [" + completedPhase + "/" + sampleData.Phases.size() + "]");
            }
        });
        Button btCompletedStep = findViewById(R.id.bt_completed_step);
        btCompletedStep.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boolean stepCompleted = false;
                Step step;
                String msg = "";
                int viewPosition = 0;
                for (int i = 0; i < adapter.getGroupCount(); i++) {
                    viewPosition++;
                    for (int j = 0; j < adapter.getChildrenCount(i); j++) {
                        viewPosition++;
                        if (adapter.getChild(i, j).Status == AppEnums.StepResult.NotCompleted) {
                            step = adapter.getChild(i, j);
                            step.Status = AppEnums.StepResult.Completed;
                            msg = step.StepName + " Completed!";
                            if (j == adapter.getGroup(i).PhaseSteps.size() - 1) {
                                adapter.getGroup(i).Status = AppEnums.StepResult.Completed;
                                completedPhase++;
                                textView.setText(sampleData.projectName + " [" + completedPhase + "/" + sampleData.Phases.size() + "]");
                                msg += "\n" + adapter.getGroup(i).PhaseName + " Completed!!!!!";
                            }
                            stepCompleted = true;
                            break;
                        }
                    }
                    if (stepCompleted) break;
                }
                if (stepCompleted) {
                    Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getApplicationContext(), "All Completed", Toast.LENGTH_LONG).show();
                }
                listView.smoothScrollToPositionFromTop(viewPosition - 1, 0);
                adapter.notifyDataSetChanged();
            }
        });
    }
    
    private Phase genNewPhase() {
        int phaseId = sampleData.Phases.size() + 1;
        Random random = new Random();
        int numberOfSteps = random.nextInt(5) + 1;
        ArrayList<Step> steps = new ArrayList<>();
        for (int j = 0; j < numberOfSteps; j++) {
            Step step = new Step("Step " + (phaseId) + "-" + (j + 1));
            steps.add(step);
        }
        return new Phase("Phase " + (phaseId) + " [" + steps.size() + "]", steps);
    }
    }
    

    ProcessFeedbackAdapter1.java:

    public class ProcessFeedbackAdapter1 extends BaseExpandableListAdapter {
    public static final String TAG = "ProcessFeedbackAdapter";
    public Context appContext;
    public ProgressOverviewData ProgressOverviewData;
    
    public ProcessFeedbackAdapter1(Context Context, ProgressOverviewData ProgressOverviewData) {
        this.appContext = Context;
        this.ProgressOverviewData = ProgressOverviewData;
    }
    
    @Override
    public int getGroupCount() {
        return ProgressOverviewData.Phases.size();
    }
    
    @Override
    public int getChildrenCount(int i) {
        return ProgressOverviewData.Phases.get(i).PhaseSteps.size();
    }
    
    @Override
    public Phase getGroup(int i) {
        return ProgressOverviewData.Phases.get(i);
    }
    
    @Override
    public Step getChild(int i, int i1) {
        return ProgressOverviewData.Phases.get(i).PhaseSteps.get(i1);
    }
    
    @Override
    public long getGroupId(int i) {
        return 0;
    }
    
    @Override
    public long getChildId(int i, int i1) {
        return 0;
    }
    
    @Override
    public boolean hasStableIds() {
        return false;
    }
    
    @Override
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        try {
            Phase curItem = getGroup(i);
            LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.progress_list_item, null);
    
            TextView ProgressMessage = view.findViewById(R.id.ProgressMessage);
            ImageView Check = view.findViewById(R.id.CheckMark);
            ImageView ErrorMark = view.findViewById(R.id.ErrorMark);
    
            int CheckVisibility = 0;
            int ErrorVisibility = 0;
            if (curItem.Status.equals(AppEnums.StepResult.NotCompleted)) {
                CheckVisibility = View.INVISIBLE;
                ErrorVisibility = View.INVISIBLE;
            } else if (curItem.Status.equals(AppEnums.StepResult.Completed)) {
                CheckVisibility = View.VISIBLE;
                ErrorVisibility = View.INVISIBLE;
            } else if (curItem.Status.equals(AppEnums.StepResult.Failed)) {
                ErrorVisibility = View.VISIBLE;
                CheckVisibility = View.INVISIBLE;
            }
    
            Check.setVisibility(CheckVisibility);
            ErrorMark.setVisibility(ErrorVisibility);
            ProgressMessage.setText(curItem.PhaseName);
    
        } catch (Exception e) {
            System.out.println("Something went wrong.");
        }
        return view;
    }
    
    @Override
    public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
        try {
            LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.progress_list_item_children, null);
    
            TextView ProgressMessage = view.findViewById(R.id.ProgressMessage);
            ImageView Check = view.findViewById(R.id.CheckMark);
            ImageView ErrorMark = view.findViewById(R.id.ErrorMark);
            Step curItem = getChild(i, i1);
    
            int CheckVisibility = 0;
            int ErrorVisibility = 0;
            if (curItem.Status == AppEnums.StepResult.NotCompleted) {
                CheckVisibility = View.INVISIBLE;
                ErrorVisibility = View.INVISIBLE;
            } else {
                if (curItem.Status == AppEnums.StepResult.Completed) {
                    CheckVisibility = View.VISIBLE;
                    ErrorVisibility = View.INVISIBLE;
                } else if (curItem.Status == AppEnums.StepResult.Failed) {
                    ErrorVisibility = View.VISIBLE;
                    CheckVisibility = View.INVISIBLE;
                }
            }
    
            ProgressMessage.setText(curItem.StepName);
    
            Check.setVisibility(CheckVisibility);
            ErrorMark.setVisibility(ErrorVisibility);
    
        } catch (Exception e) {
            System.out.println("Something went wrong.");
        }
        return view;
    }
    
    @Override
    public boolean isChildSelectable(int i, int i1) {
        return false;
    }
    }
    

    activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
    tools:context=".MainActivity">
    
    <TextView
        android:id="@+id/ProgressMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Progress Messages:"
        android:textColor="#F8F8F8"
        android:textSize="20sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    
    <Button
        android:id="@+id/bt_add_phase"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingStart="20dp"
        android:text="Add Phase"
        app:layout_constraintRight_toLeftOf="@id/bt_completed_step"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="RtlSymmetry" />
    
    <Button
        android:id="@+id/bt_completed_step"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingStart="20dp"
        android:text="Completed Step"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="RtlSymmetry" />
    
    <ImageView
        android:id="@+id/ProgressErrorContainer"
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/ProgressMessage" />
    
    <ExpandableListView
        android:id="@+id/ProgressStepsContainer"
        android:layout_width="0dp"
        android:layout_height="267dp"
        android:background="#000033"
        android:fastScrollEnabled="false"
        android:verticalScrollbarPosition="left"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/ProgressErrorContainer"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/ProgressMessage" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    progress_list_item.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="0dp">
    
    <ImageView
        android:id="@+id/CheckMark"
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@android:drawable/checkbox_on_background" />
    
    <ImageView
        android:id="@+id/ErrorMark"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:visibility="visible"
        app:layout_constraintStart_toStartOf="@+id/CheckMark"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@android:drawable/ic_delete" />
    
    <TextView
        android:id="@+id/ProgressMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textAlignment="center"
        android:textColor="#F8F8F8"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/CheckMark"
        app:layout_constraintStart_toEndOf="@+id/CheckMark"
        app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    progress_list_item_children.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:paddingStart="50dp"
    android:layout_width="wrap_content"
    android:layout_height="50dp">
    
    <ImageView
        android:id="@+id/CheckMark"
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@android:drawable/checkbox_on_background" />
    
    <ImageView
        android:id="@+id/ErrorMark"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:visibility="visible"
        app:layout_constraintStart_toStartOf="@+id/CheckMark"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@android:drawable/ic_delete" />
    
    <TextView
        android:id="@+id/ProgressMessage"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:gravity="center"
        android:textAlignment="center"
        android:textColor="#F8F8F8"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/CheckMark"
        app:layout_constraintStart_toEndOf="@+id/CheckMark"
        app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    与你的数据结构相关的类,你可以从你原来的项目中复制过来。

    【讨论】:

    • 哇,我不相信有人会帮助我。非常感谢您的努力。我会在星期一试一试?
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 2015-02-01
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多